package com.wxzz.elearing.course.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.wxpay.sdk.WXPay;
import com.google.common.collect.Lists;
import com.wxzz.elearing.course.amqp.producer.CourseProducer;
import com.wxzz.elearing.course.dto.*;
import com.wxzz.elearing.course.entity.*;
import com.wxzz.elearing.course.mapper.*;
import com.wxzz.elearing.course.service.ICurriculumSectionTopicService;
import com.wxzz.elearing.course.service.ICurriculumService;
import com.wxzz.elearing.course.service.openfeign.*;
import com.wxzz.elearing.course.vo.*;
import com.wxzz.elearning.common.aop.Idempotent;
import com.wxzz.elearning.common.bean.SmsConfig;
import com.wxzz.elearning.common.constants.OrderConstants;
import com.wxzz.elearning.common.constants.RedisConstants;
import com.wxzz.elearning.common.dto.FeignEnterpriseDto;
import com.wxzz.elearning.common.dto.FeignStudyTimeDto;
import com.wxzz.elearning.common.dto.FeignWxUserDto;
import com.wxzz.elearning.common.dto.SystemMessageMqDto;
import com.wxzz.elearning.common.exception.ServiceException;
import com.wxzz.elearning.common.utils.CodeGenerateUtils;
import com.wxzz.elearning.common.utils.ExcelTopicUtils;
import com.wxzz.elearning.common.utils.ExcelUtils;
import com.wxzz.elearning.common.utils.OpenFeignUtil;
import com.wxzz.elearning.common.vo.JgPageVo;
import com.wxzz.elearning.common.vo.ReturnVO;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.Topic;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 课程 服务实现类
 * </p>
 *
 * @author
 * @since 2021-03-10
 */
@Slf4j
@Service
public class CurriculumServiceImpl extends ServiceImpl<CurriculumMapper, Curriculum> implements ICurriculumService {

    @Autowired
    private CurriculumMapper curriculumMapper;

    @Autowired
    private CurriculumSectionMapper curriculumSectionMapper;

    @Autowired
    private IEnterpriseFeign enterpriseFeign;

    @SneakyThrows
    @Override
    public ReturnVO<JgPageVo<List<Curriculum>>> listCurriculumByCategory(HttpServletResponse response, Integer type, CurriculumDto curriculumDto, Integer isApply) {
        PageHelper.startPage(curriculumDto.getCurPage(), curriculumDto.getMaxPage());
        QueryWrapper<Curriculum> queryWrapper = new QueryWrapper();
        if (curriculumDto.getIsDocentSend() != null) {
            queryWrapper.eq("is_docent_send", curriculumDto.getIsDocentSend());
        }
        //是否为审核申请的课程 0-否 1-是  如讲师申请上架课程 企业申请到平台课程
        if (isApply != null && isApply == 1) {
            queryWrapper.ne("status", 0);
        }
        if (curriculumDto.getIsApply() != null) {
            queryWrapper.eq("is_apply", curriculumDto.getIsApply());
        }
        if (curriculumDto.getEnterpriseId() != null) {
            queryWrapper.eq("enterprise_id", curriculumDto.getEnterpriseId());
        }
        //是否为企业购买
        if (curriculumDto.getIsEnterpriseBuy() != null) {
            queryWrapper.eq("is_enterprise_buy", curriculumDto.getIsEnterpriseBuy());
        }
        //小程序端不展示禁用的课程
        if (type == 1) {
            queryWrapper.eq("is_ban", 0);
        }
        if (curriculumDto.getStatus() != null) {
            queryWrapper.eq("status", curriculumDto.getStatus());
        }
        if (StringUtils.isNotBlank(curriculumDto.getCurriculumTitle())) {
            queryWrapper.like("curriculum_title", curriculumDto.getCurriculumTitle());
        }
        if (curriculumDto.getDocentId() != null) {
            queryWrapper.eq("docent_id", curriculumDto.getDocentId());
        }
        if (curriculumDto.getCurriculumType() != null) {
//            if (curriculumDto.getCurriculumType() == 0) {
//                queryWrapper.and(qw -> qw.eq("is_apply", "1").or().eq("curriculum_type", 0));
//            } else {
            queryWrapper.eq("curriculum_type", curriculumDto.getCurriculumType());
//            }
        }
        //平台课程根据平台课程分类字段查询
        if (curriculumDto.getCurriculumType() != null && curriculumDto.getCurriculumType() == 0 && curriculumDto.getCurriculumCategoryFirstId() != null) {
            queryWrapper.eq("platform_curriculum_category_first_id", curriculumDto.getCurriculumCategoryFirstId());
        }
        if (curriculumDto.getCurriculumType() != null && curriculumDto.getCurriculumType() == 0 && curriculumDto.getCurriculumCategoryId() != null) {
            queryWrapper.eq("platform_curriculum_category_id", curriculumDto.getCurriculumCategoryId());
        }
        //企业课程根据企业课程分类字段查询
        if (curriculumDto.getCurriculumType() != null && curriculumDto.getCurriculumType() == 1 && curriculumDto.getCurriculumCategoryFirstId() != null) {
            queryWrapper.eq("enterprise_curriculum_category_first_id", curriculumDto.getCurriculumCategoryFirstId());
        }
        if (curriculumDto.getCurriculumType() != null && curriculumDto.getCurriculumType() == 1 && curriculumDto.getCurriculumCategoryId() != null) {
            queryWrapper.eq("enterprise_curriculum_category_id", curriculumDto.getCurriculumCategoryId());
        }
        queryWrapper.orderByDesc("create_time");
        curriculumMapper.selectList(new LambdaQueryWrapper<Curriculum>()
                .eq(curriculumDto.getIsDocentSend() != null, Curriculum::getIsDocentSend, curriculumDto.getIsDocentSend()));
        List<Curriculum> list = curriculumMapper.selectList(queryWrapper);
        for (Curriculum curriculum : list) {
            //企业是否购买
            if (curriculumDto.getEnterpriseId() != null) {
                queryWrapper.eq("enterprise_id", curriculumDto.getEnterpriseId());
                Curriculum isBuy = curriculumMapper.selectOne(new LambdaQueryWrapper<Curriculum>()
                        .eq(Curriculum::getEnterpriseId, curriculumDto.getEnterpriseId())
                        .eq(Curriculum::getOldCurriculumId, curriculum.getId()));
                if (isBuy != null) {
                    curriculum.setIsBuy(1);
                }
            }
            //如果是企业购买的课程,则进行特殊处理
            if (curriculum.getIsEnterpriseBuy() != null && curriculum.getIsEnterpriseBuy() == 1 && curriculumDto.getIsSynchronize() != null && curriculumDto.getIsSynchronize() == 1) {
                Curriculum oldCurriculum = curriculumMapper.selectById(curriculum.getOldCurriculumId());
                if (oldCurriculum != null) {
                    //设置原课程的基础信息
                    curriculum.setCurriculumTitle(oldCurriculum.getCurriculumTitle());
                    curriculum.setCurriculumDescribe(oldCurriculum.getCurriculumDescribe());
                    curriculum.setCurriculumBanner(oldCurriculum.getCurriculumBanner());
                    curriculum.setCurriculumFile(oldCurriculum.getCurriculumFile());
                    curriculum.setCurriculumFileName(oldCurriculum.getCurriculumFileName());
                    curriculum.setCurriculumFileSize(oldCurriculum.getCurriculumFileSize());
                }
            }
            if (curriculum.getDocentId() != null) {
                //调用讲师模块
                ReturnVO<String> stringReturnVO = docentFeign.selectDocentById(curriculum.getDocentId());
                JSONObject jsonObject = OpenFeignUtil.getJSONObject(stringReturnVO);
                if (jsonObject != null) {
                    curriculum.setDocentName(jsonObject.getString("docentName"));
                }
            }
            if (curriculum.getEnterpriseId() != null && curriculum.getEnterpriseId() != 0) {
                //调用企业模块
                ReturnVO<String> stringReturnVO = enterpriseFeign.selectEnterpriseById(curriculum.getEnterpriseId());
                JSONObject jsonObject = OpenFeignUtil.getJSONObject(stringReturnVO);
                curriculum.setEnterpriseName(jsonObject.getString("enterpriseName"));
            }
            //课程时长
            List<CurriculumSection> curriculumSectionList = curriculumSectionMapper.selectList(new LambdaQueryWrapper<CurriculumSection>().eq(CurriculumSection::getCurriculumId, curriculum.getId()));
            Long countTime = 0L;
            for (CurriculumSection curriculumSection : curriculumSectionList) {
                countTime = countTime + curriculumSection.getVideoTime();
            }
            curriculum.setCurriculumTime((double) countTime / 60);
            //章节数量
            Integer sectionCount = curriculumSectionMapper.selectCount(new LambdaQueryWrapper<CurriculumSection>().eq(CurriculumSection::getCurriculumId, curriculum.getId()));
            curriculum.setCurriculumSectionNum(sectionCount);
            //课件
            //curriculum.setCurriculumFileVos(this.getCurriculumFileVos(curriculum));
            //学习人数
            Integer curriculumStudyNum = wxUserCurriculumMapper.selectCount(new LambdaQueryWrapper<WxUserCurriculum>()
                    .eq(WxUserCurriculum::getCurriculumId, curriculum.getId())
                    .eq(WxUserCurriculum::getStatus, 1));
            curriculum.setCurriculumStudyNum(curriculumStudyNum);
            //curriculum.setCurriculumStudyNum(redisTemplate.opsForSet().size(RedisConstants.CURRICULUM_STUDY_NUM + curriculum.getId()));
        }
        if (curriculumDto.getIsExport() != null && curriculumDto.getIsExport() == 1) {
            ExcelUtils.exportExcel(list, "课程列表", "课程列表", Curriculum.class, "课程列表", response);
            return new ReturnVO("课程列表查询成功", null);
        }
        for (Curriculum curriculum : list) {
            if (curriculum.getCurriculumFileVos() != null) {
                StringBuilder curriculumFiles = new StringBuilder();
                StringBuilder curriculumFileNames = new StringBuilder();
                StringBuilder curriculumFileSizes = new StringBuilder();
                for (CurriculumFileVo curriculumFileVo : curriculum.getCurriculumFileVos()) {
                    curriculumFiles.append(curriculumFileVo.getCurriculumFile()).append(",");
                    curriculumFileNames.append(curriculumFileVo.getCurriculumFileName()).append(",");
                    curriculumFileSizes.append(curriculumFileVo.getCurriculumFileSize()).append(",");
                }
                curriculum.setCurriculumFile(curriculumFiles.toString());
                curriculum.setCurriculumFileName(curriculumFileNames.toString());
                curriculum.setCurriculumFileSize(curriculumFileSizes.toString());
            }
        }
        return new ReturnVO("课程列表查询成功", new JgPageVo(new PageInfo<>(list)));
    }

    @Autowired
    private WxUserCurriculumMapper wxUserCurriculumMapper;

    @Override
    public ReturnVO listCurriculumByCategory4train(Long enterpriseId, Long wxUserId, CurriculumByCategory4trainDto curriculumByCategory4trainDto) {
        PageHelper.startPage(curriculumByCategory4trainDto.getCurPage(), curriculumByCategory4trainDto.getMaxPage());
        List<Curriculum> curriculumList = wxUserCurriculumMapper.listCurriculumByCategory4train(enterpriseId, wxUserId, curriculumByCategory4trainDto);
        return new ReturnVO("课程列表查询成功", new JgPageVo(new PageInfo<>(curriculumList)));
    }

    @Autowired
    private IDocentFeign docentFeign;


    @Override
    public ReturnVO<CurriculumVo> selectCurriculumDetail(Long enterpriseId, Long curriculumId) {
        Curriculum curriculum = curriculumMapper.selectById(curriculumId);
        if (curriculum == null) {
            throw new ServiceException("该课程已不存在");
        }
        //如果是企业购买的课程,则进行特殊处理
        if (curriculum.getIsEnterpriseBuy() != null && curriculum.getIsEnterpriseBuy() == 1) {
            Curriculum oldCurriculum = curriculumMapper.selectById(curriculum.getOldCurriculumId());
            if (oldCurriculum != null) {
                //设置原课程的基础信息
                curriculum.setCurriculumTitle(oldCurriculum.getCurriculumTitle());
                curriculum.setCurriculumDescribe(oldCurriculum.getCurriculumDescribe());
                curriculum.setCurriculumBanner(oldCurriculum.getCurriculumBanner());
                curriculum.setCurriculumFile(oldCurriculum.getCurriculumFile());
                curriculum.setCurriculumFileName(oldCurriculum.getCurriculumFileName());
                curriculum.setCurriculumFileSize(oldCurriculum.getCurriculumFileSize());
            }
        }
        if (curriculum.getDocentId() != null) {
            //调用讲师模块
            ReturnVO<String> stringReturnVO = docentFeign.selectDocentById(curriculum.getDocentId());
            JSONObject jsonObject = OpenFeignUtil.getJSONObject(stringReturnVO);
            curriculum.setDocent(jsonObject.toJSONString());
            if (jsonObject != null) {
                curriculum.setDocentName(jsonObject.getString("docentName"));
            }
        }
        CurriculumVo curriculumVo = new CurriculumVo();
        BeanUtils.copyProperties(curriculum, curriculumVo);
        List<CurriculumSection> curriculumSections = curriculumSectionMapper.listCurriculumSectionByCurriculumId(curriculumId);
        curriculumVo.setCurriculumSections(curriculumSections);
        //学习人数
        Integer curriculumStudyNum = wxUserCurriculumMapper.selectCount(new LambdaQueryWrapper<WxUserCurriculum>()
                .eq(WxUserCurriculum::getCurriculumId, curriculumId)
                .eq(WxUserCurriculum::getStatus, 1));
        curriculumVo.setCurriculumStudyNum(curriculumStudyNum);
        //curriculumVo.setCurriculumStudyNum(redisTemplate.opsForSet().size(RedisConstants.CURRICULUM_STUDY_NUM + curriculum.getId()));
        //企业是否购买
        Curriculum isBuy = curriculumMapper.selectOne(new LambdaQueryWrapper<Curriculum>()
                .eq(Curriculum::getEnterpriseId, enterpriseId)
                .eq(Curriculum::getOldCurriculumId, curriculum.getId()));
        if (isBuy != null) {
            curriculumVo.setIsBuy(1);
        }
        //课程时长
        List<CurriculumSection> curriculumSectionList = Lists.newArrayList();
        if (curriculum.getOldCurriculumId() != null) {
            curriculumSectionList = curriculumSectionMapper.selectList(new LambdaQueryWrapper<CurriculumSection>().eq(CurriculumSection::getCurriculumId, curriculum.getOldCurriculumId()));
        } else {
            curriculumSectionList = curriculumSectionMapper.selectList(new LambdaQueryWrapper<CurriculumSection>().eq(CurriculumSection::getCurriculumId, curriculum.getId()));
        }
        Long countTime = 0L;
        for (CurriculumSection curriculumSection : curriculumSectionList) {
            countTime = countTime + curriculumSection.getVideoTime();
        }
        curriculumVo.setCurriculumTime((double) countTime / 60);
        // 计算文件
        curriculumVo.setCurriculumFileVos(this.getCurriculumFileVos(curriculumVo));
        return new ReturnVO("后台课程详情查询成功", curriculumVo);
    }


    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Idempotent
    @Override
    public ReturnVO<Curriculum> wxSelectCurriculumDetail(Long enterpriseId, Long wxUserId, Long curriculumId) {
        //学习人数+1
        //redisTemplate.opsForSet().add(RedisConstants.CURRICULUM_STUDY_NUM + curriculumId, JSONObject.toJSONString(wxUserId));
        Curriculum curriculum = curriculumMapper.selectById(curriculumId);
        Optional.ofNullable(curriculum).orElseThrow(() -> new ServiceException("该课程已不存在"));
        //如果是企业购买的课程,则进行特殊处理
        if (curriculum.getIsEnterpriseBuy() != null && curriculum.getIsEnterpriseBuy() == 1) {
            Curriculum oldCurriculum = curriculumMapper.selectById(curriculum.getOldCurriculumId());
            if (oldCurriculum != null) {
                //设置原课程的基础信息
                curriculum.setCurriculumTitle(oldCurriculum.getCurriculumTitle());
                curriculum.setCurriculumDescribe(oldCurriculum.getCurriculumDescribe());
                curriculum.setCurriculumBanner(oldCurriculum.getCurriculumBanner());
                curriculum.setCurriculumFile(oldCurriculum.getCurriculumFile());
                curriculum.setCurriculumFileName(oldCurriculum.getCurriculumFileName());
                curriculum.setCurriculumFileSize(oldCurriculum.getCurriculumFileSize());
            }
        }
        if (curriculum != null && curriculum.getDocentId() != null) {
            //调用讲师模块
            ReturnVO<String> stringReturnVO = docentFeign.selectDocentById(curriculum.getDocentId());
            if (!"200".equals(stringReturnVO.getCode())) {
                throw new ServiceException(stringReturnVO.getMessage());
            }
            curriculum.setDocent(stringReturnVO.getData());
        }
        //用户学习的视频进度
        String see = redisTemplate.opsForValue().get(RedisConstants.CURRICULUM_LAST_SEE_TIME + wxUserId + ":" + curriculumId);
        if (StringUtils.isNotBlank(see)) {
            String[] split = see.split(":");
            if (StringUtils.isNotBlank(split[0]) && StringUtils.isNotBlank(split[1])) {
                curriculum.setSeeTime(Long.valueOf(split[0]));
                curriculum.setSeeStatus(Integer.valueOf(split[1]));
            }
        }
        //用户浏览后将记录到我的课程
        WxUserCurriculum wxUserCurriculum = wxUserCurriculumMapper.selectOne(new LambdaQueryWrapper<WxUserCurriculum>()
                .eq(WxUserCurriculum::getWxUserId, wxUserId)
                .eq(WxUserCurriculum::getCurriculumId, curriculumId));
        if (wxUserCurriculum == null) {
            //添加记录
            wxUserCurriculum = new WxUserCurriculum();
            wxUserCurriculum.setWxUserId(wxUserId);
            wxUserCurriculum.setCurriculumId(curriculumId);
            wxUserCurriculum.setEnterpriseId(enterpriseId);
            wxUserCurriculumMapper.insert(wxUserCurriculum);
        }
        //计算学习进度
        curriculum.setStudySchedule(getStudySchedule(wxUserCurriculum.getWxUserId(), wxUserCurriculum.getCurriculumId()));
        //是否购买
        if (wxUserCurriculum.getStatus() != null) {
            curriculum.setIsBuy(wxUserCurriculum.getStatus());
        }
        //星级
//        List<WxUserCurriculum> wxUserCurricula = wxUserCurriculumMapper.selectList(new LambdaQueryWrapper<WxUserCurriculum>()
//                .eq(WxUserCurriculum::getCurriculumId, curriculumId)
//                .ne(WxUserCurriculum::getStartLevel, -1));
//        BigDecimal allStart = new BigDecimal("0.00");
//        for (WxUserCurriculum userCurriculum : wxUserCurricula) {
//            allStart = allStart.add(userCurriculum.getStartLevel());
//        }
        //BigDecimal start = allStart.divide(new BigDecimal(String.valueOf(wxUserCurricula.size())));
        //curriculum.setStartLevel( start.setScale( 0, BigDecimal.ROUND_DOWN ).longValue());// 向下取整
        //是否收藏
        if (wxUserCurriculum.getIsCollect() != null) {
            curriculum.setIsCollect(wxUserCurriculum.getIsCollect());
        }
        //课件
        curriculum.setCurriculumFileVos(this.getCurriculumFileVos(curriculum));
        //学习人数
        Integer curriculumStudyNum = wxUserCurriculumMapper.selectCount(new LambdaQueryWrapper<WxUserCurriculum>()
                .eq(WxUserCurriculum::getCurriculumId, curriculumId)
                .eq(WxUserCurriculum::getStatus, 1));
        curriculum.setCurriculumStudyNum(curriculumStudyNum);
        //课程时长
        List<CurriculumSection> curriculumSectionList = Lists.newArrayList();
        if (curriculum.getOldCurriculumId() != null) {
            curriculumSectionList = curriculumSectionMapper.selectList(new LambdaQueryWrapper<CurriculumSection>().eq(CurriculumSection::getCurriculumId, curriculum.getOldCurriculumId()));
        } else {
            curriculumSectionList = curriculumSectionMapper.selectList(new LambdaQueryWrapper<CurriculumSection>().eq(CurriculumSection::getCurriculumId, curriculum.getId()));
        }
        Long countTime = 0L;
        for (CurriculumSection curriculumSection : curriculumSectionList) {
            countTime = countTime + curriculumSection.getVideoTime();
        }
        curriculum.setCurriculumTime((double) countTime / 60);
        //curriculum.setCurriculumStudyNum(redisTemplate.opsForSet().size(RedisConstants.CURRICULUM_STUDY_NUM + curriculum.getId()));
        //是否已评星
        Query query = new Query();
        query.addCriteria(Criteria.where("curriculumId").is(curriculumId));
        query.addCriteria(Criteria.where("wxUserId").is(wxUserId));
        List<CurriculumCommentVo> curriculumCommentVos = mongoTemplate.find(query, CurriculumCommentVo.class);
        int starCount = 0;
        if (curriculumCommentVos.size() != 0) {
            for (int i = 0; i < curriculumCommentVos.size(); i++) {
                if (curriculumCommentVos.get(i).getStar() != null) {
                    starCount += curriculumCommentVos.get(i).getStar();
                }
            }
        }
        if (starCount > 0) {
            curriculum.setIsStar(1);
        } else {
            curriculum.setIsStar(0);
        }
        //评论数量
        Query qy = new Query();
        qy.addCriteria(Criteria.where("curriculumId").is(curriculumId));
        long count = mongoTemplate.count(qy, "curriculumCommentCollection");
        curriculum.setCommentCount(count);
        return new ReturnVO("课程详情查询成功", curriculum);
    }

    @Autowired
    private WxUserCurriculumSectionMapper wxUserCurriculumSectionMapper;

    @Autowired
    private CurriculumUnitMapper curriculumUnitMapper;

    @Override
    public ReturnVO<List<CurriculumUnit>> listCurriculumSection(Long wxUserId, Long curriculumId) {
        Long nowCurriculumId = curriculumId;
        //List<CurriculumSection> curriculumSections = curriculumSectionMapper.listCurriculumSectionByCurriculumId(curriculumId);
//        for (CurriculumSection curriculumSection : curriculumSections) {
//            //查询单元名称
//            CurriculumUnit curriculumUnit = curriculumUnitMapper.selectById(curriculumSection.getCurriculumUnitId());
//            if (curriculumUnit != null) {
//                curriculumSection.setUnitName(curriculumUnit.getUnitName());
//            }
//            //判断用户是否通过
//            Integer passNum = wxUserCurriculumSectionMapper.countWxUserCurriculumSectionPassNum(wxUserId, curriculumSection.getId());
//            if (passNum > 0) {
//                curriculumSection.setIsPass(1);
//            }
//        }
        Curriculum curriculum = curriculumMapper.selectById(curriculumId);
        Optional.ofNullable(curriculum).orElseThrow(() -> new ServiceException("该课程不存在"));
        //如果是企业购买的课程,则进行特殊处理
        if (curriculum.getIsEnterpriseBuy() != null && curriculum.getIsEnterpriseBuy() == 1) {
            Curriculum oldCurriculum = curriculumMapper.selectById(curriculum.getOldCurriculumId());
            if (oldCurriculum != null) {
                curriculumId = oldCurriculum.getId();
            }
        }
        List<CurriculumUnit> curriculumUnits = curriculumUnitMapper.selectList(new LambdaQueryWrapper<CurriculumUnit>().eq(CurriculumUnit::getCurriculumId, curriculumId)
                .orderByAsc(CurriculumUnit::getCurriculumUnitSort));
        //0-未通过/未考试 1-已通过
        Integer open = 1;
        for (CurriculumUnit curriculumUnit : curriculumUnits) {
            //查询单元下的章节
            List<CurriculumSection> curriculumSectionList = curriculumSectionMapper.selectList(new LambdaQueryWrapper<CurriculumSection>().eq(CurriculumSection::getCurriculumUnitId, curriculumUnit.getId()));
            //判断用户是否通过
            if (wxUserId != null) {
                for (CurriculumSection curriculumSection : curriculumSectionList) {
                    Integer passNum = wxUserCurriculumSectionMapper.countWxUserCurriculumSectionPassNum(wxUserId, curriculumSection.getId(), nowCurriculumId);
                    if (passNum > 0) {
                        curriculumSection.setIsPass(1);
                    }
                    //如果之前通过并且当前未通过
                    if (open == 1 && passNum == 0) {
                        open = 0;
                        curriculumSection.setIsPass(0);
                    }
                }
            }
            curriculumUnit.setCurriculumSections(curriculumSectionList);
        }
        return new ReturnVO("课程章节列表查询成功", curriculumUnits);
    }

    @Autowired
    private CurriculumSectionTopicMapper curriculumSectionTopicMapper;

    @Autowired
    private CurriculumSectionTopicAnswerMapper curriculumSectionTopicAnswerMapper;

    @Override
    public ReturnVO<List<CurriculumSectionTopic>> listCurriculumSectionTopic(Long curriculumSectionId, Integer topicCategory) {
        List<CurriculumSectionTopic> curriculumSectionTopics = curriculumSectionTopicMapper.listCurriculumSectionTopicByCurriculumSectionId(curriculumSectionId, topicCategory);
        //测评答案选项
        curriculumSectionTopics.forEach(curriculumSectionTopic -> curriculumSectionTopic
                .setCurriculumSectionTopicAnswerList(curriculumSectionTopicAnswerMapper.listCurriculumSectionTopicId(curriculumSectionTopic.getId())));
        return new ReturnVO<>("测评列表查询成功", curriculumSectionTopics);
    }

    @Autowired
    private DocentCurriculumStatisticsDataMapper docentCurriculumStatisticsDataMapper;

    @Idempotent
    @Override
    public ReturnVO saveCurriculum(Long adminUserId, Curriculum curriculum) {
        if (curriculum.getDocentId() == null) {
            throw new ServiceException("请传入讲师id");
        }
        curriculum.setAdminUserId(adminUserId);
        if (curriculum.getCurriculumFileVos() != null) {
            StringBuilder curriculumFiles = new StringBuilder();
            StringBuilder curriculumFileNames = new StringBuilder();
            StringBuilder curriculumFileSizes = new StringBuilder();
            for (CurriculumFileVo curriculumFileVo : curriculum.getCurriculumFileVos()) {
                curriculumFiles.append(curriculumFileVo.getCurriculumFile()).append(",");
                curriculumFileNames.append(curriculumFileVo.getCurriculumFileName()).append(",");
                curriculumFileSizes.append(curriculumFileVo.getCurriculumFileSize()).append(",");
            }
            curriculum.setCurriculumFile(curriculumFiles.toString());
            curriculum.setCurriculumFileName(curriculumFileNames.toString());
            curriculum.setCurriculumFileSize(curriculumFileSizes.toString());
        }
        curriculumMapper.insert(curriculum);
        //讲师英雄榜只统计企业的课程
        if (curriculum.getEnterpriseId() != null) {
            //统计讲师发布的课程
            DocentCurriculumStatisticsData docentCurriculumStatisticsData = docentCurriculumStatisticsDataMapper.selectOne(new LambdaQueryWrapper<DocentCurriculumStatisticsData>()
                    .eq(DocentCurriculumStatisticsData::getDocentId, curriculum.getDocentId())
                    .eq(DocentCurriculumStatisticsData::getEnterpriseId, curriculum.getEnterpriseId())
                    .eq(DocentCurriculumStatisticsData::getSaveTime, LocalDate.now().toString()));
            if (docentCurriculumStatisticsData == null) {
                docentCurriculumStatisticsData = new DocentCurriculumStatisticsData();
                docentCurriculumStatisticsData.setCurriculumNum(1);
                docentCurriculumStatisticsData.setDocentId(curriculum.getDocentId());
                docentCurriculumStatisticsData.setSaveTime(LocalDate.now().toString());
                docentCurriculumStatisticsData.setEnterpriseId(curriculum.getEnterpriseId());
                docentCurriculumStatisticsDataMapper.insert(docentCurriculumStatisticsData);
            } else {
                docentCurriculumStatisticsData.setCurriculumNum(docentCurriculumStatisticsData.getCurriculumNum() + 1);
                docentCurriculumStatisticsDataMapper.updateById(docentCurriculumStatisticsData);
            }
        }
        return new ReturnVO("课程新增成功", curriculum.getId());
    }

    @Override
    public ReturnVO updateCurriculum(Curriculum curriculum) {
        Curriculum temp = curriculumMapper.selectById(curriculum.getId());
        if (temp == null) {
            throw new ServiceException("该id对应课程不存在");
        }
//        if (temp.getStatus() != 0) {
//            throw new ServiceException("该课程未处于下架状态,无法修改内容");
//        }
        if (curriculum.getCurriculumFileVos() != null) {
            StringBuilder curriculumFiles = new StringBuilder();
            StringBuilder curriculumFileNames = new StringBuilder();
            StringBuilder curriculumFileSizes = new StringBuilder();
            for (CurriculumFileVo curriculumFileVo : curriculum.getCurriculumFileVos()) {
                curriculumFiles.append(curriculumFileVo.getCurriculumFile()).append(",");
                curriculumFileNames.append(curriculumFileVo.getCurriculumFileName()).append(",");
                curriculumFileSizes.append(curriculumFileVo.getCurriculumFileSize()).append(",");
            }
            curriculum.setCurriculumFile(curriculumFiles.toString());
            curriculum.setCurriculumFileName(curriculumFileNames.toString());
            curriculum.setCurriculumFileSize(curriculumFileSizes.toString());
        }
        curriculumMapper.updateById(curriculum);
        return new ReturnVO("课程修改成功", curriculum.getId());
    }

    @Autowired
    private IPlatformParamServiceFeign platformParamServiceFeign;

    @Override
    public ReturnVO isBanCurriculum(Curriculum curriculum) {
        Curriculum result = curriculumMapper.selectById(curriculum.getId());
        Optional.ofNullable(result).orElseThrow(() -> new ServiceException("该课程不存在"));
        Curriculum ban = new Curriculum();
        ban.setId(curriculum.getId());
        ban.setIsBan(curriculum.getIsBan());
        curriculumMapper.updateById(ban);

        FeignEnterpriseDto feignEnterpriseDto = enterpriseFeign.selectEnterpriseDtoById(result.getEnterpriseId());
        String coursePhone = platformParamServiceFeign.selectOne("coursePhone");
        if (curriculum.getIsBan() != null && curriculum.getIsBan() == 1 && result.getEnterpriseId() != 0) {
            //发送给企业
            SystemMessageMqDto enterpriseSystemMessageMqDto = new SystemMessageMqDto();
            enterpriseSystemMessageMqDto.setMessageType(1);
            enterpriseSystemMessageMqDto.setMessageDetail("很抱歉,您在五星智造平台的" + result.getCurriculumTitle() + "课程被封禁,详情请致电客服:" + coursePhone);
            enterpriseSystemMessageMqDto.setMessageTitle("课程封禁");
            enterpriseSystemMessageMqDto.setWxUserIds(new ArrayList<Long>() {
                {
                    add(result.getEnterpriseId());
                }
            });
            courseProducer.ackMQSender(JSONObject.toJSONString(enterpriseSystemMessageMqDto));
            SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
            if (curriculum.getIsMms() != null && curriculum.getIsMms() == 1 && feignEnterpriseDto != null && StringUtils.isNotBlank(feignEnterpriseDto.getPhone())) {
                systemMessageMqDto.setPhones(new ArrayList<String>() {
                    {
                        add(feignEnterpriseDto.getPhone());
                    }
                });
                systemMessageMqDto.setTemplateId(SmsConfig.courseBanId);
                systemMessageMqDto.setParams(new ArrayList<String>() {
                    {
                        add(result.getCurriculumTitle());
                        add(LocalDate.now().toString());
                        add(LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
                        add(coursePhone);
                    }
                });
            }
            //查看该企业是否有院长
            if (feignEnterpriseDto != null && feignEnterpriseDto.getWxUserId() != null) {
                systemMessageMqDto.setMessageDetail("很抱歉,您在五星智造平台的" + result.getCurriculumTitle() + "课程被封禁,详情请致电客服:" + coursePhone);
                systemMessageMqDto.setMessageTitle("课程封禁");
                systemMessageMqDto.setWxUserIds(new ArrayList<Long>() {
                    {
                        add(feignEnterpriseDto.getWxUserId());
                    }
                });
                courseProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
            }
        }
        return new ReturnVO("解禁/禁用成功", curriculum.getId());
    }

    @Override
    public ReturnVO deleteCurriculum(Long curriculumId) {
        curriculumMapper.deleteById(curriculumId);
        return new ReturnVO("课程删除成功", curriculumId);
    }

    @Override
    public ReturnVO updateStatus(Long curriculumId, Integer isDocent) {
        Curriculum curriculum = curriculumMapper.selectById(curriculumId);
        if (curriculum == null) {
            throw new ServiceException("该课程已不存在");
        }
        //讲师需要审核
        //curriculum.setStatus(isDocent == 1 ? 1 : 2); todo
        curriculum.setStatus(2);
        curriculumMapper.updateById(curriculum);
        //讲师发布需要审核 课程审核记录
        if (isDocent == 1) {
            CurriculumCheckLog curriculumCheckLog = new CurriculumCheckLog();
            curriculumCheckLog.setCurriculumId(curriculum.getId());
            curriculumCheckLog.setDocentId(curriculum.getDocentId());
            curriculumCheckLog.setCheckType("创建课程");
            curriculumCheckLog.setCurriculumTitle(curriculum.getCurriculumTitle());
        } else {
            FeignEnterpriseDto feignEnterpriseDto = enterpriseFeign.selectEnterpriseDtoById(curriculum.getEnterpriseId());
            SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
            systemMessageMqDto.setMessageDetail(feignEnterpriseDto.getEnterpriseName() + "企业上架了课程 请及时查看");
            systemMessageMqDto.setMessageTitle("企业课程上架");
            systemMessageMqDto.setMessageType(2);
            systemMessageMqDto.setWxUserIds(new ArrayList<Long>() {
                {
                    add(0L);
                }
            });
            courseProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
        }
        return new ReturnVO("课程状态修改成功", curriculumId);
    }


    @Autowired
    private CourseProducer courseProducer;

    @Override
    public ReturnVO updateStatusDown(Long curriculumId) {
        Curriculum curriculum = curriculumMapper.selectById(curriculumId);
        curriculum.setStatus(0); // TODO: 修改为下架状态（而不是使用默认状态），并且接收通知方式、下架理由等
        curriculumMapper.updateById(curriculum);
        FeignEnterpriseDto feignEnterpriseDto = enterpriseFeign.selectEnterpriseDtoById(curriculum.getEnterpriseId());
        if (curriculum.getEnterpriseId() != 0) {
            //发送给企业
            SystemMessageMqDto enterpriseSystemMessageMqDto = new SystemMessageMqDto();
            enterpriseSystemMessageMqDto.setMessageType(1);
            enterpriseSystemMessageMqDto.setMessageDetail(curriculum.getCurriculumTitle() + "课程已经被下架");
            enterpriseSystemMessageMqDto.setMessageTitle("课程下架");
            enterpriseSystemMessageMqDto.setWxUserIds(new ArrayList<Long>() {
                {
                    add(curriculum.getEnterpriseId());
                }
            });
            courseProducer.ackMQSender(JSONObject.toJSONString(enterpriseSystemMessageMqDto));
        }

        //发送给院长
        SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
        if (feignEnterpriseDto != null && StringUtils.isNotBlank(feignEnterpriseDto.getPhone())) {
            systemMessageMqDto.setPhones(new ArrayList<String>() {
                {
                    add(feignEnterpriseDto.getPhone());
                }
            });
            systemMessageMqDto.setTemplateId(SmsConfig.courseDownId);
            systemMessageMqDto.setParams(new ArrayList<String>() {
                {
                    add(curriculum.getCurriculumTitle());
                    add(LocalDate.now().toString());
                    add(LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
                }
            });
        }
        //查看该企业是否有院长
        if (feignEnterpriseDto != null && feignEnterpriseDto.getWxUserId() != null) {
            systemMessageMqDto.setMessageDetail(curriculum.getCurriculumTitle() + "课程已经被下架");
            systemMessageMqDto.setMessageTitle("课程下架");
            systemMessageMqDto.setWxUserIds(new ArrayList<Long>() {
                {
                    add(feignEnterpriseDto.getWxUserId());
                }
            });
            courseProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
        }
        return new ReturnVO("下架成功", curriculumId);
    }

    @Override
    public ReturnVO updatePlatformStatus(UpdatePlatformStatusDto updatePlatformStatusDto) {
        Curriculum curriculum = curriculumMapper.selectById(updatePlatformStatusDto.getCurriculumId());
        Optional.ofNullable(curriculum).orElseThrow(() -> new ServiceException("该课程对应课程id不存在"));
        curriculum.setCurriculumPrice(updatePlatformStatusDto.getCurriculumPrice());
        curriculum.setCurriculumPriceEnterprise(updatePlatformStatusDto.getCurriculumPriceEnterprise());
        curriculum.setCurriculumOldPrice(updatePlatformStatusDto.getCurriculumOldPrice());
        curriculum.setCurriculumOldPriceEnterprise(updatePlatformStatusDto.getCurriculumOldPriceEnterprise());
        curriculum.setRemark(updatePlatformStatusDto.getRemark());
        //改为企业上架到平台的课程
        curriculum.setCurriculumType(0);
        curriculum.setStatus(1);
        curriculum.setIsApply(1);
        curriculumMapper.updateById(curriculum);
        //发送平台消息
        FeignEnterpriseDto feignEnterpriseDto = enterpriseFeign.selectEnterpriseDtoById(curriculum.getEnterpriseId());
        SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
        systemMessageMqDto.setMessageDetail(feignEnterpriseDto.getEnterpriseName() + "企业将课程上架至平台了，请及时审核");
        systemMessageMqDto.setMessageTitle("企业上架至平台课程");
        systemMessageMqDto.setMessageType(2);
        systemMessageMqDto.setWxUserIds(new ArrayList<Long>() {
            {
                add(0L);
            }
        });
        courseProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
        return new ReturnVO("课程状态修改成功", updatePlatformStatusDto.getCurriculumId());
    }


    @Override
    @Transactional
    public ReturnVO saveCurriculumSection(CurriculumSection curriculumSection) {
        Curriculum temp = curriculumMapper.selectById(curriculumSection.getCurriculumId());
        Optional.ofNullable(temp).orElseThrow(() -> new ServiceException("该课程对应课程id不存在"));
        if (curriculumSection.getId() == null) {
            curriculumSectionMapper.insert(curriculumSection);
        } else {
            //更新 将原有的试题删除重新添加
            curriculumSectionMapper.updateById(curriculumSection);
            List<CurriculumSectionTopic> curriculumSectionTopics = curriculumSectionTopicMapper.selectList(new LambdaQueryWrapper<CurriculumSectionTopic>()
                    .eq(CurriculumSectionTopic::getCurriculumSectionId, curriculumSection.getId()));
            curriculumSectionTopics.forEach(curriculumSectionTopic -> {
                //删除试题
                curriculumSectionTopicMapper.deleteById(curriculumSectionTopic.getId());
                //删除答案
                curriculumSectionTopicAnswerMapper.deleteCurriculumSectionTopicAnswerByCurriculumSectionTopicId(curriculumSectionTopic.getId());
            });
        }
        //题目总分
        BigDecimal allScore = new BigDecimal("0.00");
        if (curriculumSection.getCurriculumSectionTopics() != null) {
            //添加试题
            for (CurriculumSectionTopic curriculumSectionTopic : curriculumSection.getCurriculumSectionTopics()) {
                curriculumSectionTopic.setId(null);
                curriculumSectionTopic.setCurriculumSectionId(curriculumSection.getId());
                curriculumSectionTopicMapper.insert(curriculumSectionTopic);
                if (curriculumSectionTopic.getCurriculumSectionTopicAnswerList() != null) {
                    //添加试题答案选项
                    for (CurriculumSectionTopicAnswer curriculumSectionTopicAnswer : curriculumSectionTopic.getCurriculumSectionTopicAnswerList()) {
                        curriculumSectionTopicAnswer.setId(null);
                        curriculumSectionTopicAnswer.setCurriculumSectionTopicId(curriculumSectionTopic.getId());
                        curriculumSectionTopicAnswerMapper.insert(curriculumSectionTopicAnswer);
                        allScore = allScore.add(curriculumSectionTopicAnswer.getScore());
                    }
                }
            }
        }
        if (allScore.compareTo(curriculumSection.getQualified()) == -1) {
            throw new ServiceException("合格标准不能大于总分");
        }
        //查询所有学习该课程的用户
        List<WxUserCurriculum> wxUserCurricula = wxUserCurriculumMapper.selectList(new LambdaQueryWrapper<WxUserCurriculum>()
                .eq(WxUserCurriculum::getCurriculumId, temp.getId()).select(WxUserCurriculum::getWxUserId));
        List<Long> wxUserIds = new ArrayList<>();
        wxUserCurricula.stream().forEach(c -> wxUserIds.add(c.getWxUserId()));
        SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
        systemMessageMqDto.setMessageDetail(temp.getCurriculumTitle() + "的章节有变动");
        systemMessageMqDto.setMessageTitle("章节变动");
        systemMessageMqDto.setWxUserIds(wxUserIds);
        //发送变动的消息
        courseProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
        return new ReturnVO("课程章节新增或修改成功", curriculumSection.getId());
    }

    @Autowired
    private ICurriculumSectionTopicService curriculumSectionTopicService;

    @Override
    public ReturnVO selectCurriculumSectionDetail(Long curriculumSectionId) {
        CurriculumSection curriculumSection = curriculumSectionMapper.selectById(curriculumSectionId);
        Optional.ofNullable(curriculumSection).orElseThrow(() -> new ServiceException("该章节不存在"));
        //查询测评试题
        ReturnVO<List<CurriculumSectionTopic>> listReturnVO = curriculumSectionTopicService.listCurriculumSectionTopicByCurriculumSectionTopicId(curriculumSectionId, 0);
        curriculumSection.setCurriculumSectionTopics(listReturnVO.getData());
        return new ReturnVO("章节详情查询成功", curriculumSection);
    }


    @Override
    public ReturnVO<List<CurriculumUnit>> listCurriculumUnit(Long curriculumId) {
        return new ReturnVO("课程单元查询成功", curriculumUnitMapper.selectList(new LambdaQueryWrapper<CurriculumUnit>()
                .eq(CurriculumUnit::getCurriculumId, curriculumId)));
    }

    @Override
    public ReturnVO saveCurriculumUnit(List<CurriculumUnit> curriculumUnits) {
        for (CurriculumUnit curriculumUnit : curriculumUnits) {
            curriculumUnitMapper.insert(curriculumUnit);
        }
        return new ReturnVO("课程单元新增成功", null);
    }

    @Override
    public ReturnVO deleteCurriculumUnitById(Long curriculumUnitId) {
        CurriculumUnit curriculumUnit = curriculumUnitMapper.selectById(curriculumUnitId);
        Optional.ofNullable(curriculumUnit).orElseThrow(() -> new ServiceException("该单元不存在"));
        Integer count = curriculumSectionMapper.selectCount(new LambdaQueryWrapper<CurriculumSection>()
                .eq(CurriculumSection::getCurriculumUnitId, curriculumUnitId));
        if (count > 0) {
            throw new ServiceException("该单元下有章节,无法删除");
        }
        curriculumUnitMapper.deleteById(curriculumUnitId);
        return new ReturnVO("课程单元删除成功", curriculumUnitId);
    }

    @Override
    public ReturnVO<JgPageVo<List<Curriculum>>> listCurriculumByDocentId(CurriculumByDocentDto curriculumByDocentDto) {
        PageHelper.startPage(curriculumByDocentDto.getCurPage(), curriculumByDocentDto.getMaxPage());
        if (curriculumByDocentDto.getDocentId() == null) {
            throw new ServiceException("请传入讲师id");
        }
        List<Curriculum> curriculumList = curriculumMapper.listCurriculumByDocentId(curriculumByDocentDto.getDocentId());
        for (Curriculum curriculum : curriculumList) {
            //课程时长
            List<CurriculumSection> curriculumSectionList = curriculumSectionMapper.selectList(new LambdaQueryWrapper<CurriculumSection>().eq(CurriculumSection::getCurriculumId, curriculum.getId()));
            Long countTime = 0L;
            for (CurriculumSection curriculumSection : curriculumSectionList) {
                countTime = countTime + curriculumSection.getVideoTime();
            }
            curriculum.setCurriculumTime((double) countTime / 60);
            //章节数量
            Integer sectionCount = curriculumSectionMapper.selectCount(new LambdaQueryWrapper<CurriculumSection>().eq(CurriculumSection::getCurriculumId, curriculum.getId()));
            curriculum.setCurriculumSectionNum(sectionCount);
            //课件
            //curriculum.setCurriculumFileVos(this.getCurriculumFileVos(curriculum));
            //学习人数
            Integer curriculumStudyNum = wxUserCurriculumMapper.selectCount(new LambdaQueryWrapper<WxUserCurriculum>()
                    .eq(WxUserCurriculum::getCurriculumId, curriculum.getId())
                    .eq(WxUserCurriculum::getStatus, 1));
            curriculum.setCurriculumStudyNum(curriculumStudyNum);
        }
        return new ReturnVO("讲师课程查询成功", new JgPageVo(new PageInfo<>(curriculumList)));
    }

    @Autowired
    private IWxPayFeign wxPayFeign;

    @Idempotent
    @Transactional
    @Override
    public ReturnVO enterpriseBuyCurriculum(JSONObject jsonObject, Long curriculumId) {
        //接口幂等处理
        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(RedisConstants.WX_USER_COMMENT + jsonObject.getLong("id"), String.valueOf(jsonObject.getLong("id")), 5, TimeUnit.SECONDS);
        if (!Boolean.TRUE.equals(aBoolean)) {
            throw new ServiceException("请重新进入确认是否已经支付成功,以免重复支付");
        }
        Curriculum curriculum = curriculumMapper.selectById(curriculumId);
        Optional.ofNullable(curriculum).orElseThrow(() -> new ServiceException("该课程对应课程id不存在"));
        Curriculum isBuy = curriculumMapper.selectOne(new LambdaQueryWrapper<Curriculum>()
                .eq(Curriculum::getOldCurriculumId, curriculumId)
                .eq(Curriculum::getEnterpriseId, jsonObject.getLong("enterpriseId")));
        if (isBuy != null) {
            throw new ServiceException("企业已经购买该课程");
        }
        Map<String, String> sendMap = new HashMap<>();
        sendMap.put("curriculumId", String.valueOf(curriculumId));
        sendMap.put("enterpriseId", jsonObject.getString("enterpriseId"));
        sendMap.put("adminUserId", jsonObject.getString("id"));
        sendMap.put("username", jsonObject.getString("username"));
        //如果参数有null 支付会报错
        if (StringUtils.isNotBlank(jsonObject.getString("phone"))) {
            sendMap.put("phone", jsonObject.getString("phone"));
        }
        sendMap.put("modelType", OrderConstants.MODEL_TYPE_CURRICULUM.toString());
        sendMap.put("userType", OrderConstants.USER_TYPE_ENTERPRISE_ADMIN.toString());
        sendMap.put("out_trade_no", CodeGenerateUtils.generateProductCode());
        sendMap.put("applyNo", CodeGenerateUtils.generateProductCode());
        sendMap.put("orderTitle", "企业购买课程id:" + curriculumId);
        //如果免费直接返回购买成功
        if ("0.00".equals(curriculum.getCurriculumPriceEnterprise().toString())) {
            copyNewCurriculum(jsonObject.getLong("enterpriseId"), curriculumId, 0L);
            return new ReturnVO("购买成功", 1);
        }
        sendMap.put("payMoney", curriculum.getCurriculumPriceEnterprise().toString());
        BigDecimal curriculumPriceEnterprise = curriculum.getCurriculumPriceEnterprise();
        String amt = String.valueOf(Double.parseDouble(curriculumPriceEnterprise.toString()) * 100);
        sendMap.put("total_fee", amt.substring(0, amt.lastIndexOf(".")));
        sendMap.put("body", "精工课程购买");
        Map<String, String> map = wxPayFeign.doUnifiedOrder(sendMap);
        //copyNewCurriculum(jsonObject.getLong("enterpriseId"), curriculumId);
        return new ReturnVO("课程订单生成成功", map);
    }

    @Override
    public void copyNewCurriculum(Long enterpriseId, Long curriculumId, Long orderId) {
        //将数据拷贝一份给购买的企业 查询放前 插入放后 因为插入后会将原id覆盖
        Curriculum curriculum = curriculumMapper.selectById(curriculumId);
        Optional.ofNullable(curriculum).orElseThrow(() -> new ServiceException("该课程对应课程id不存在"));
        Curriculum isBuy = curriculumMapper.selectOne(new LambdaQueryWrapper<Curriculum>()
                .eq(Curriculum::getOldCurriculumId, curriculumId)
                .eq(Curriculum::getEnterpriseId, enterpriseId));
        if (isBuy != null) {
            //throw new ServiceException("企业已经购买该课程");
            return;
        }
        //将原id拷贝
        curriculum.setOldCurriculumId(curriculumId);
        //查询单元
        List<CurriculumUnit> curriculumUnits = curriculumUnitMapper.selectList(new LambdaQueryWrapper<CurriculumUnit>()
                .eq(CurriculumUnit::getCurriculumId, curriculum.getId()));

        curriculum.setId(null);
        curriculum.setIsEnterpriseBuy(1);
        curriculum.setCurriculumType(1);
        curriculum.setUserOrderId(orderId);
        curriculum.setEnterpriseId(enterpriseId);
        //如果为企业上架的课程 则清除
        curriculum.setIsApply(0);
        curriculum.setCurriculumPrice(new BigDecimal("0.00"));
        curriculum.setCurriculumPriceEnterprise(new BigDecimal("0.00"));
        //拷贝课程
        curriculumMapper.insert(curriculum);
//        //循环单元
//        for (CurriculumUnit curriculumUnit : curriculumUnits) {
//            //查询章节
//            List<CurriculumSection> curriculumSectionList = curriculumSectionMapper.selectList(new LambdaQueryWrapper<CurriculumSection>()
//                    .eq(CurriculumSection::getCurriculumId, curriculumId)
//                    .eq(CurriculumSection::getCurriculumUnitId, curriculumUnit.getId()));
//            curriculumUnit.setId(null);
//            curriculumUnit.setCurriculumId(curriculum.getId());
//            //拷贝单元
//            curriculumUnitMapper.insert(curriculumUnit);
//            //循环章节
//            for (CurriculumSection curriculumSection : curriculumSectionList) {
//                //查询章节试题
//                List<CurriculumSectionTopic> curriculumSectionTopics = curriculumSectionTopicMapper.selectList(new LambdaQueryWrapper<CurriculumSectionTopic>()
//                        .eq(CurriculumSectionTopic::getCurriculumSectionId, curriculumSection.getId()));
//                curriculumSection.setId(null);
//                curriculumSection.setCreateTime(null);
//                curriculumSection.setCurriculumId(curriculum.getId());
//                curriculumSection.setCurriculumUnitId(curriculumUnit.getId());
//                //拷贝章节
//                curriculumSectionMapper.insert(curriculumSection);
//                for (CurriculumSectionTopic curriculumSectionTopic : curriculumSectionTopics) {
//                    //查询试题答案
//                    List<CurriculumSectionTopicAnswer> curriculumSectionTopicAnswers = curriculumSectionTopicAnswerMapper.selectList(new LambdaQueryWrapper<CurriculumSectionTopicAnswer>()
//                            .eq(CurriculumSectionTopicAnswer::getCurriculumSectionTopicId, curriculumSectionTopic.getId()));
//                    curriculumSectionTopic.setId(null);
//                    curriculumSectionTopic.setCreateTime(null);
//                    curriculumSectionTopic.setCurriculumSectionId(curriculumSectionTopic.getCurriculumSectionId());
//                    //拷贝章节试题
//                    curriculumSectionTopicMapper.insert(curriculumSectionTopic);
//                    curriculumSectionTopicAnswers.forEach(curriculumSectionTopicAnswer -> {
//                        curriculumSectionTopicAnswer.setId(null);
//                        curriculumSectionTopicAnswer.setCreateTime(null);
//                        curriculumSectionTopicAnswer.setCurriculumSectionTopicId(curriculumSectionTopic.getId());
//                        //拷贝试题答案
//                        curriculumSectionTopicAnswerMapper.insert(curriculumSectionTopicAnswer);
//                    });
//                }
//            }
//        }

    }

    @Autowired
    private CurriculumCheckLogMapper curriculumCheckLogMapper;

    @Transactional
    @Override
    public ReturnVO checkCurriculum(CheckCurriculumDto checkCurriculumDto) {
        Curriculum curriculum = curriculumMapper.selectById(checkCurriculumDto.getCurriculumId());
        Optional.ofNullable(curriculum).orElseThrow(() -> new ServiceException("该课程已不存在"));
        curriculum.setStatus(checkCurriculumDto.getStatus());
        curriculum.setPlatformCurriculumCategoryFirstId(checkCurriculumDto.getPlatformCurriculumCategoryFirstId());
        curriculum.setPlatformCurriculumCategoryId(checkCurriculumDto.getPlatformCurriculumCategoryId());

        //课程审核记录
        CurriculumCheckLog curriculumCheckLog = new CurriculumCheckLog();
        curriculumCheckLog.setCurriculumTitle(curriculum.getCurriculumTitle());
        curriculumCheckLog.setCurriculumId(curriculum.getId());
        FeignEnterpriseDto feignEnterpriseDto = enterpriseFeign.selectEnterpriseDtoById(curriculum.getEnterpriseId());
        if (checkCurriculumDto.getStatus() == 2) {
            curriculumCheckLog.setCheckType("审核通过");
            curriculum.setCurriculumType(0);
            curriculum.setCreateTime(LocalDateTime.now());
            //如果是企业上架到平台的课程则发消息
            if (curriculum.getIsApply() == 1) {
                SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
                if (checkCurriculumDto.getIsMms() != null && checkCurriculumDto.getIsMms() == 1 && feignEnterpriseDto != null && StringUtils.isNotBlank(feignEnterpriseDto.getPhone())) {
                    systemMessageMqDto.setPhones(new ArrayList<String>() {
                        {
                            add(feignEnterpriseDto.getPhone());
                        }
                    });
                    systemMessageMqDto.setTemplateId(SmsConfig.enterpriseCourseApplyPassId);
                    systemMessageMqDto.setParams(new ArrayList<String>() {
                        {
                            add(curriculum.getCurriculumTitle());
                            add(LocalDate.now().toString());
                            add(LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
                        }
                    });
                }
                if (feignEnterpriseDto != null && feignEnterpriseDto.getWxUserId() != null) {
                    systemMessageMqDto.setMessageDetail("恭喜你,您的" + curriculum.getCurriculumTitle() + "课程上架至平台已在" + LocalDate.now().toString() + "时通过");
                    systemMessageMqDto.setMessageTitle("课程上架至平台");
                    systemMessageMqDto.setWxUserIds(new ArrayList<Long>() {
                        {
                            add(feignEnterpriseDto.getWxUserId());
                        }
                    });
                }
                courseProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
                //企业默认购买自己上架至平台的课程
                copyNewCurriculum(curriculum.getEnterpriseId(), curriculum.getId(), null);
            }
        }
        if (checkCurriculumDto.getStatus() == 3) {
            curriculumCheckLog.setCheckType("审核未通过");
            //如果是企业上架到平台的课程则发消息
            if (curriculum.getIsApply() == 1) {
                //todo 上架到平台未通过消息模板没有
            }
        }
        curriculumCheckLog.setDocentId(curriculum.getDocentId());
        curriculumCheckLog.setRemark(checkCurriculumDto.getRemark());
        curriculumCheckLogMapper.insert(curriculumCheckLog);
        curriculumMapper.updateById(curriculum);

        return new ReturnVO("课程审核成功", checkCurriculumDto.getCurriculumId());
    }


    @Override
    public ReturnVO<JgPageVo<List<CurriculumCheckLog>>> listCurriculumCheckLogByDocentId(CurriculumCheckLogDto curriculumCheckLogDto) {
        PageHelper.startPage(curriculumCheckLogDto.getCurPage(), curriculumCheckLogDto.getMaxPage());
        List<CurriculumCheckLog> curriculumCheckLogs = curriculumCheckLogMapper.selectList(new LambdaQueryWrapper<CurriculumCheckLog>()
                .eq(CurriculumCheckLog::getDocentId, curriculumCheckLogDto.getDocentId()));
        return new ReturnVO("课程审核记录查询成功", new JgPageVo<>(new PageInfo(curriculumCheckLogs)));
    }

    @Autowired
    private WxUserCurriculumDataMapper wxUserCurriculumDataMapper;

    @Override
    public ReturnVO<String> selectWxUserCurriculumDataByWxUserId(Long wxUserId) {
        WxUserCurriculumData wxUserCurriculumData = wxUserCurriculumDataMapper.selectOne(new LambdaQueryWrapper<WxUserCurriculumData>()
                .eq(WxUserCurriculumData::getWxUserId, wxUserId));
        return new ReturnVO("查询学习课程数据成功", JSONObject.toJSONString(wxUserCurriculumData));
    }

    @Override
    public ReturnVO<JSONObject> selectCurriculum4EnterpriseByOrderId(Long orderId) {
        Curriculum curriculum = curriculumMapper.selectOne(new LambdaQueryWrapper<Curriculum>()
                .eq(Curriculum::getUserOrderId, orderId));
        Optional.ofNullable(curriculum).orElseThrow(() -> new ServiceException("课程已经不存在"));
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("enterpriseId", curriculum.getEnterpriseId());
        jsonObject.put("curriculumType", curriculum.getCurriculumType());
        return new ReturnVO<>("课程信息查询成功", jsonObject);
    }

    @Autowired
    private IWxUserApiFeign wxUserApiFeign;

    /**
     * 计算学习进度
     *
     * @param wxUserId
     * @param curriculumId
     * @return
     */
    @Override
    public BigDecimal getStudySchedule(Long wxUserId, Long curriculumId) {
        //查询学习进度
        //查询该课程下所有章节
        List<CurriculumSection> curriculumSectionList = curriculumSectionMapper.selectList(new LambdaQueryWrapper<CurriculumSection>()
                .eq(CurriculumSection::getCurriculumId, curriculumId));
        Integer allCount = curriculumSectionList.size();
        Integer passCount = 0;
        for (CurriculumSection curriculumSection : curriculumSectionList) {
            //查询用户完成的章节
            Integer pass = wxUserCurriculumSectionMapper.selectCount(new LambdaQueryWrapper<WxUserCurriculumSection>()
                    .eq(WxUserCurriculumSection::getWxUserId, wxUserId)
                    .eq(WxUserCurriculumSection::getCurriculumId, curriculumId)
                    .eq(WxUserCurriculumSection::getCurriculumSectionId, curriculumSection.getId())
                    .eq(WxUserCurriculumSection::getIsPass, 1));
            //如果有通过的
            if (pass > 0) {
                passCount = passCount + 1;
            }
        }
        //计算进度
        BigDecimal divide = new BigDecimal("0.00");
        if (!passCount.equals(0)) {
            divide = new BigDecimal(String.valueOf(passCount)).multiply(new BigDecimal("100"))
                    .divide(new BigDecimal(String.valueOf(allCount)), 2, BigDecimal.ROUND_HALF_UP);
        }
        return divide;
//        //查询学习进度
//        //查询该课程下所有章节
//        List<CurriculumSection> curriculumSectionList = curriculumSectionMapper.selectList(new LambdaQueryWrapper<CurriculumSection>()
//                .eq(CurriculumSection::getCurriculumId, curriculumId));
//        Integer allCount = curriculumSectionList.size();
//        Integer passCount = 0;
//        for (CurriculumSection curriculumSection : curriculumSectionList) {
//            //查询用户完成的章节
//            Integer pass = wxUserCurriculumSectionMapper.selectCount(new LambdaQueryWrapper<WxUserCurriculumSection>()
//                    .eq(WxUserCurriculumSection::getWxUserId, wxUserId)
//                    .eq(WxUserCurriculumSection::getCurriculumSectionId, curriculumSection.getId())
//                    .eq(WxUserCurriculumSection::getIsPass, 1));
//            //如果有通过的
//            if (pass > 0) {
//                passCount = passCount + 1;
//            }
//        }
//        //计算进度
//        BigDecimal divide = new BigDecimal("0.00");
//        if (!passCount.equals(0)) {
//            divide = new BigDecimal(String.valueOf(passCount)).multiply(new BigDecimal("100"))
//                    .divide(new BigDecimal(String.valueOf(allCount)), 2, BigDecimal.ROUND_HALF_UP);
//        }
//        return divide;
    }

    @Override
    public ReturnVO<JgPageVo<List<WxUserCurriculum>>> selectWxUserByCurriculum(WxUserByCurriculumDto wxUserByCurriculumDto) {
        PageHelper.startPage(wxUserByCurriculumDto.getCurPage(), wxUserByCurriculumDto.getMaxPage());
        QueryWrapper<WxUserCurriculum> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("create_time");
        queryWrapper.eq("curriculum_id", wxUserByCurriculumDto.getCurriculumId());
        queryWrapper.eq("status", 1);
        if (wxUserByCurriculumDto.getEnterpriseId() != null) {
            queryWrapper.eq("enterprise_id", wxUserByCurriculumDto.getEnterpriseId());
        }
        List<WxUserCurriculum> wxUserCurricula = wxUserCurriculumMapper.selectList(queryWrapper);
        for (WxUserCurriculum wxUserCurriculum : wxUserCurricula) {
            wxUserCurriculum.setStudySchedule(getStudySchedule(wxUserCurriculum.getWxUserId(), wxUserCurriculum.getCurriculumId()));
            //查看学习位置
            wxUserCurriculum.setSectionName(redisTemplate.opsForValue().get(RedisConstants.SECTION_LAST_SEE + wxUserCurriculum.getWxUserId() + ":" + wxUserCurriculum.getCurriculumId()));
            //查询用户信息
            FeignWxUserDto feignWxUserDto = wxUserApiFeign.selectFeignWxUserDtoByWxUserId(wxUserCurriculum.getWxUserId());
            wxUserCurriculum.setIcon(feignWxUserDto.getIcon());
            wxUserCurriculum.setPhone(feignWxUserDto.getPhone());
            wxUserCurriculum.setNickname(feignWxUserDto.getNickname());
            wxUserCurriculum.setOrganizationName(feignWxUserDto.getOrganizationName());
            wxUserCurriculum.setLastOrganizationName(feignWxUserDto.getLastOrganizationName());
            wxUserCurriculum.setIdentityName(feignWxUserDto.getIdentityName());
            //学习时长
            ReturnVO<String> stringReturnVO = selectWxUserCurriculumDataByWxUserId(wxUserCurriculum.getWxUserId());
            JSONObject jsonObject = OpenFeignUtil.getJSONObject(stringReturnVO);
            if (jsonObject.getLong("studyTime") != null) {
                wxUserCurriculum.setStudyTime((double) jsonObject.getLong("studyTime") / (60 * 60));
                wxUserCurriculum.setTodayStudyTime((double) jsonObject.getLong("todayStudyTime") / (60 * 60));
                wxUserCurriculum.setFinishClass(jsonObject.getLong("finishClass"));
            }
        }
        return new ReturnVO<>("人员学习情况查询成功", new JgPageVo<>(new PageInfo(wxUserCurricula)));
    }


    @Override
    public ReturnVO selectEnterpriseByCurriculum(WxUserByCurriculumDto wxUserByCurriculumDto) {
        PageHelper.startPage(wxUserByCurriculumDto.getCurPage(), wxUserByCurriculumDto.getMaxPage());
        List<Curriculum> curriculumList = curriculumMapper.selectList(new LambdaQueryWrapper<Curriculum>()
                .eq(Curriculum::getOldCurriculumId, wxUserByCurriculumDto.getCurriculumId()).select(Curriculum::getEnterpriseId));
        List<FeignEnterpriseDto> enterpriseDtoList = Lists.newArrayList();
        for (Curriculum curriculum : curriculumList) {
            FeignEnterpriseDto enterpriseDto = enterpriseFeign.selectEnterpriseDtoById(curriculum.getEnterpriseId());
            enterpriseDtoList.add(enterpriseDto);
        }
        JgPageVo<Object> objectJgPageVo = new JgPageVo<>(new PageInfo(curriculumList));
        objectJgPageVo.setData(enterpriseDtoList);
        return new ReturnVO("企业学习情况查询成功", objectJgPageVo);
    }

    @Override
    public ReturnVO<WxUserCurriculumStatisticsVo> selectWxUserCurriculumStatisticsVoByCurriculum(Long curriculumId) {
        Curriculum curriculum = curriculumMapper.selectById(curriculumId);
        Optional.ofNullable(curriculum).orElseThrow(() -> new ServiceException("该课程已经不存在"));
        WxUserCurriculumStatisticsVo wxUserCurriculumStatisticsVo = new WxUserCurriculumStatisticsVo();
        //学习人数
        Integer curriculumStudyNum = wxUserCurriculumMapper.selectCount(new LambdaQueryWrapper<WxUserCurriculum>()
                .eq(WxUserCurriculum::getCurriculumId, curriculumId)
                .eq(WxUserCurriculum::getStatus, 1));
        wxUserCurriculumStatisticsVo.setCurriculumStudyNum(curriculumStudyNum);
        //Long curriculumStudyNum = redisTemplate.opsForSet().size(RedisConstants.CURRICULUM_STUDY_NUM + curriculum.getId());
        //查询所有的章节
        List<CurriculumSection> curriculumSectionList = curriculumSectionMapper.selectList(new LambdaQueryWrapper<CurriculumSection>()
                .eq(CurriculumSection::getCurriculumId, curriculumId));
        //总学习时长
        double curriculumStudyTime = 0;
        Integer allPassCount = 0;
        Integer allUnPassCount = 0;
        for (CurriculumSection curriculumSection : curriculumSectionList) {
            //查询所有通过的章节数量
            Integer passCount = wxUserCurriculumSectionMapper.selectCount(new LambdaQueryWrapper<WxUserCurriculumSection>()
                    .eq(WxUserCurriculumSection::getCurriculumSectionId, curriculumSection.getId())
                    .eq(WxUserCurriculumSection::getIsPass, 1));
            allPassCount = allPassCount + passCount;
            //累加学习时长
            curriculumStudyTime = curriculumStudyTime + curriculumSection.getVideoTime();
            //查询未通过的章节数量
            Integer unPassCount = wxUserCurriculumSectionMapper.selectCount(new LambdaQueryWrapper<WxUserCurriculumSection>()
                    .eq(WxUserCurriculumSection::getCurriculumSectionId, curriculumSection.getId())
                    .eq(WxUserCurriculumSection::getIsPass, 0));
            allUnPassCount = allUnPassCount + unPassCount;
        }
        //课程达标率 总通过数量/总次数
        Integer allSectionCount = allPassCount + allUnPassCount;
        if (!allSectionCount.equals(0)) {
            wxUserCurriculumStatisticsVo.setCurriculumStandard((double) allPassCount / allSectionCount * 100);
        }
        wxUserCurriculumStatisticsVo.setCurriculumStudyTime((double) curriculumStudyTime / (60 * 60));
        //人均学习时长
        if (!curriculumStudyNum.equals(0)) {
            wxUserCurriculumStatisticsVo.setCurriculumStudyTimeByPerson((double) curriculumStudyTime / curriculumStudyNum / (60 * 60));
        }
        //收藏次数
        Integer isCollect = wxUserCurriculumMapper.selectCount(new LambdaQueryWrapper<WxUserCurriculum>()
                .eq(WxUserCurriculum::getCurriculumId, curriculumId)
                .eq(WxUserCurriculum::getIsCollect, 1));
        wxUserCurriculumStatisticsVo.setCurriculumCollection(isCollect);
        return new ReturnVO<>("根据课程id查询人员学习情况数据统计成功", wxUserCurriculumStatisticsVo);
    }

    @Override
    public ReturnVO<WxUserCurriculumStatisticsVo> selectEnterpriseCurriculumStatisticsVoByCurriculum(Long curriculumId) {
        Curriculum curriculum = curriculumMapper.selectById(curriculumId);
        Optional.ofNullable(curriculum).orElseThrow(() -> new ServiceException("该课程已经不存在"));
        WxUserCurriculumStatisticsVo wxUserCurriculumStatisticsVo = new WxUserCurriculumStatisticsVo();
        //学习人数
        Integer curriculumStudyNum = wxUserCurriculumMapper.selectCount(new LambdaQueryWrapper<WxUserCurriculum>()
                .eq(WxUserCurriculum::getCurriculumId, curriculumId)
                .eq(WxUserCurriculum::getStatus, 1)
                .ne(WxUserCurriculum::getEnterpriseId, 0));
        wxUserCurriculumStatisticsVo.setCurriculumStudyNum(curriculumStudyNum);
        //Long curriculumStudyNum = redisTemplate.opsForSet().size(RedisConstants.CURRICULUM_STUDY_NUM + curriculum.getId());
        //查询所有的章节
        List<CurriculumSection> curriculumSectionList = curriculumSectionMapper.selectList(new LambdaQueryWrapper<CurriculumSection>()
                .eq(CurriculumSection::getCurriculumId, curriculumId));
        //总学习时长
        double curriculumStudyTime = 0;
        Integer allPassCount = 0;
        Integer allUnPassCount = 0;
        for (CurriculumSection curriculumSection : curriculumSectionList) {
            //查询所有通过的章节数量
            Integer passCount = wxUserCurriculumSectionMapper.selectCount(new LambdaQueryWrapper<WxUserCurriculumSection>()
                    .eq(WxUserCurriculumSection::getCurriculumSectionId, curriculumSection.getId())
                    .eq(WxUserCurriculumSection::getIsPass, 1)
                    .ne(WxUserCurriculumSection::getEnterpriseId, 0));
            allPassCount = allPassCount + passCount;
            //累加学习时长
            curriculumStudyTime = curriculumStudyTime + curriculumSection.getVideoTime();
            //查询未通过的章节数量
            Integer unPassCount = wxUserCurriculumSectionMapper.selectCount(new LambdaQueryWrapper<WxUserCurriculumSection>()
                    .eq(WxUserCurriculumSection::getCurriculumSectionId, curriculumSection.getId())
                    .eq(WxUserCurriculumSection::getIsPass, 0)
                    .ne(WxUserCurriculumSection::getEnterpriseId, 0));
            allUnPassCount = allUnPassCount + unPassCount;
        }
        //课程达标率 总通过数量/总次数
        Integer allSectionCount = allPassCount + allUnPassCount;
        if (!allSectionCount.equals(0)) {
            wxUserCurriculumStatisticsVo.setCurriculumStandard((double) allPassCount / allSectionCount * 100);
        }
        wxUserCurriculumStatisticsVo.setCurriculumStudyTime((double) curriculumStudyTime / (60 * 60));
        //人均学习时长
        if (!curriculumStudyNum.equals(0)) {
            wxUserCurriculumStatisticsVo.setCurriculumStudyTimeByPerson((double) curriculumStudyTime / curriculumStudyNum / (60 * 60));
        }
        //收藏次数
        Integer isCollect = wxUserCurriculumMapper.selectCount(new LambdaQueryWrapper<WxUserCurriculum>()
                .eq(WxUserCurriculum::getCurriculumId, curriculumId)
                .eq(WxUserCurriculum::getIsCollect, 1)
                .ne(WxUserCurriculum::getEnterpriseId, 0));
        wxUserCurriculumStatisticsVo.setCurriculumCollection(isCollect);
        return new ReturnVO<>("根据课程id查询人员学习情况数据统计成功", wxUserCurriculumStatisticsVo);
    }

    @Override
    public ReturnVO<EnterpriseCurriculumVo> selectEnterpriseCurriculumVoByCurriculum(Long enterpriseId, Long curriculumId) {
        Curriculum curriculum = curriculumMapper.selectById(curriculumId);
        Optional.ofNullable(curriculum).orElseThrow(() -> new ServiceException("该课程已经不存在"));
        EnterpriseCurriculumVo enterpriseCurriculumVo = new EnterpriseCurriculumVo();
        //查询该企业下的该课程所有学习情况
        List<WxUserCurriculumStatisticsData> wxUserCurriculumStatisticsData = wxUserCurriculumStatisticsDataMapper.selectList(new LambdaQueryWrapper<WxUserCurriculumStatisticsData>()
                .eq(WxUserCurriculumStatisticsData::getCurriculumId, curriculumId)
                .eq(WxUserCurriculumStatisticsData::getEnterpriseId, enterpriseId)
                .orderByDesc(WxUserCurriculumStatisticsData::getSaveTime));
        //学习时长
        double studyTime = 0;
        //完成课时
        Long finishClass = 0L;
        for (WxUserCurriculumStatisticsData wxUserCurriculumStatisticsDatum : wxUserCurriculumStatisticsData) {
            studyTime = studyTime + wxUserCurriculumStatisticsDatum.getStudyTime();
            finishClass = finishClass + wxUserCurriculumStatisticsDatum.getFinishClass();
        }
        //数据更新时间
        if (wxUserCurriculumStatisticsData.size() != 0) {
            //取最后一条数据的创建时间
            enterpriseCurriculumVo.setStudyTimeUpdateTime(wxUserCurriculumStatisticsData.get(wxUserCurriculumStatisticsData.size() - 1).getCreateTime());
            enterpriseCurriculumVo.setFinishClassUpdateTime(wxUserCurriculumStatisticsData.get(wxUserCurriculumStatisticsData.size() - 1).getCreateTime());
        }
        enterpriseCurriculumVo.setStudyTime((double) studyTime / (60 * 60));
        enterpriseCurriculumVo.setFinishClass(finishClass);
        //每日学习时长记录
        //展示近30天柱状图
        String lastMonth = LocalDate.now().minusDays(30).toString();
        List<EnterpriseCurriculumDto> enterpriseCurriculumDtos = wxUserCurriculumStatisticsDataMapper.listEnterpriseCurriculumDto(curriculumId, enterpriseId, lastMonth, LocalDate.now().toString());
        List<Double> studyTime4days = Lists.newArrayList();
        List<String> studyDays = Lists.newArrayList();
//        for (EnterpriseCurriculumDto enterpriseCurriculumDto : enterpriseCurriculumDtos) {
//            studyTime4days.add((double) enterpriseCurriculumDto.getStudyTime() / (60 * 60));
//            studyDays.add(enterpriseCurriculumDto.getSaveTime());
//        }
        //上个月时间
        LocalDate startTime = LocalDate.parse(lastMonth);
        LocalDate endTime = LocalDate.now();
        for (int i = 0; i <= endTime.getDayOfYear() - startTime.getDayOfYear(); i++) {
            studyDays.add(startTime.plusDays(i).toString());
        }
        for (String s : studyDays) {
            double studyTime4day = 0;
            //日期匹配
            for (EnterpriseCurriculumDto enterpriseCurriculumDto : enterpriseCurriculumDtos) {
                if (s.equals(enterpriseCurriculumDto.getSaveTime())) {
                    studyTime4day = (double) enterpriseCurriculumDto.getStudyTime() / (60 * 60);
                }
            }
            studyTime4days.add(studyTime4day);
        }
        enterpriseCurriculumVo.setStudyTime4days(studyTime4days);
        enterpriseCurriculumVo.setStudyDays(studyDays);
        return new ReturnVO<>("查询企业学习情况详情成功", enterpriseCurriculumVo);
    }

    @Override
    public ReturnVO selectCurriculumVoByCurriculum(Long curriculumId) {
        Curriculum curriculum = curriculumMapper.selectById(curriculumId);
        Optional.ofNullable(curriculum).orElseThrow(() -> new ServiceException("该课程已经不存在"));
        EnterpriseCurriculumVo enterpriseCurriculumVo = new EnterpriseCurriculumVo();
        //查询该企业下的该课程所有学习情况
        List<WxUserCurriculumStatisticsData> wxUserCurriculumStatisticsData = wxUserCurriculumStatisticsDataMapper.selectList(new LambdaQueryWrapper<WxUserCurriculumStatisticsData>()
                .eq(WxUserCurriculumStatisticsData::getCurriculumId, curriculumId)
                .orderByDesc(WxUserCurriculumStatisticsData::getSaveTime));
        //学习时长
        double studyTime = 0;
        //完成课时
        Long finishClass = 0L;
        for (WxUserCurriculumStatisticsData wxUserCurriculumStatisticsDatum : wxUserCurriculumStatisticsData) {
            studyTime = studyTime + wxUserCurriculumStatisticsDatum.getStudyTime();
            finishClass = finishClass + wxUserCurriculumStatisticsDatum.getFinishClass();
        }
        //数据更新时间
        if (wxUserCurriculumStatisticsData.size() != 0) {
            //取最后一条数据的创建时间
            enterpriseCurriculumVo.setStudyTimeUpdateTime(wxUserCurriculumStatisticsData.get(wxUserCurriculumStatisticsData.size() - 1).getCreateTime());
            enterpriseCurriculumVo.setFinishClassUpdateTime(wxUserCurriculumStatisticsData.get(wxUserCurriculumStatisticsData.size() - 1).getCreateTime());
        }
        enterpriseCurriculumVo.setStudyTime((double) studyTime / (60 * 60));
        enterpriseCurriculumVo.setFinishClass(finishClass);
        //每日学习时长记录
        //展示近30天柱状图
        String lastMonth = LocalDate.now().minusDays(30).toString();
        List<EnterpriseCurriculumDto> enterpriseCurriculumDtos = wxUserCurriculumStatisticsDataMapper.listCurriculumDto(curriculumId, lastMonth, LocalDate.now().toString());
        List<Double> studyTime4days = Lists.newArrayList();
        List<String> studyDays = Lists.newArrayList();
//        for (EnterpriseCurriculumDto enterpriseCurriculumDto : enterpriseCurriculumDtos) {
//            studyTime4days.add((double) enterpriseCurriculumDto.getStudyTime() / (60 * 60));
//            studyDays.add(enterpriseCurriculumDto.getSaveTime());
//        }
        //上个月时间
        LocalDate startTime = LocalDate.parse(lastMonth);
        LocalDate endTime = LocalDate.now();
        for (int i = 0; i <= endTime.getDayOfYear() - startTime.getDayOfYear(); i++) {
            studyDays.add(startTime.plusDays(i).toString());
        }
        for (String s : studyDays) {
            double studyTime4day = 0;
            //日期匹配
            for (EnterpriseCurriculumDto enterpriseCurriculumDto : enterpriseCurriculumDtos) {
                if (s.equals(enterpriseCurriculumDto.getSaveTime())) {
                    studyTime4day = (double) enterpriseCurriculumDto.getStudyTime() / (60 * 60);
                }
            }
            studyTime4days.add(studyTime4day);
        }
        enterpriseCurriculumVo.setStudyTime4days(studyTime4days);
        enterpriseCurriculumVo.setStudyDays(studyDays);
        return new ReturnVO<>("查询学习情况详情成功", enterpriseCurriculumVo);
    }


    @Override
    public ReturnVO<WxUserCurriculumVo> selectWxUserCurriculumVoByWxUserId(Long wxUserId, Long curriculumId) {
        WxUserCurriculumVo wxUserCurriculumVo = new WxUserCurriculumVo();
        FeignWxUserDto feignWxUserDto = wxUserApiFeign.selectFeignWxUserDtoByWxUserId(wxUserId);
        BeanUtils.copyProperties(feignWxUserDto, wxUserCurriculumVo);
        WxUserCurriculumStatisticsData wxUserCurriculumData = wxUserCurriculumStatisticsDataMapper.selectOne(new LambdaQueryWrapper<WxUserCurriculumStatisticsData>()
                .eq(WxUserCurriculumStatisticsData::getWxUserId, wxUserId)
                .eq(WxUserCurriculumStatisticsData::getCurriculumId, curriculumId));
        if (wxUserCurriculumData != null) {
            wxUserCurriculumVo.setStudyTime((double) wxUserCurriculumData.getStudyTime() / (60 * 60));
            wxUserCurriculumVo.setFinishClass(wxUserCurriculumData.getFinishClass());
            //不存在更新时间则取创建时间
            if (wxUserCurriculumData.getUpdateTime() == null) {
                wxUserCurriculumVo.setStudyTimeUpdateTime(wxUserCurriculumData.getCreateTime());
                wxUserCurriculumVo.setFinishClassUpdateTime(wxUserCurriculumData.getCreateTime());
            } else {
                wxUserCurriculumVo.setStudyTimeUpdateTime(wxUserCurriculumData.getUpdateTime());
                wxUserCurriculumVo.setFinishClassUpdateTime(wxUserCurriculumData.getUpdateTime());
            }
            //该课程学习时长
            wxUserCurriculumVo.setCurriculumStudyTime((double) wxUserCurriculumData.getStudyTime() / (60 * 60));
            wxUserCurriculumVo.setStudyStartTime(wxUserCurriculumData.getCreateTime());
        }
        //该课程学习时长
//        WxUserCurriculum wxUserCurriculum = wxUserCurriculumMapper.selectOne(new LambdaQueryWrapper<WxUserCurriculum>()
//                .eq(WxUserCurriculum::getCurriculumId, curriculumId)
//                .eq(WxUserCurriculum::getWxUserId, wxUserId));
//        if (wxUserCurriculum != null) {
//            wxUserCurriculumVo.setCurriculumStudyTime(wxUserCurriculum.getCurriculumStudyTime());
//            wxUserCurriculumVo.setStudyStartTime(wxUserCurriculum.getCreateTime());
//        }

        //学习进度
        wxUserCurriculumVo.setStudySchedule(getStudySchedule(wxUserId, curriculumId));
        //测试情况
        List<CurriculumSection> curriculumSectionList = curriculumSectionMapper.selectList(new LambdaQueryWrapper<CurriculumSection>()
                .eq(CurriculumSection::getCurriculumId, curriculumId));
        //未通过次数
        Integer allNum = 0;
        Integer unPass = 0;
        for (CurriculumSection curriculumSection : curriculumSectionList) {
            List<WxUserCurriculumSection> wxUserCurriculumSections = wxUserCurriculumSectionMapper.selectList(new LambdaQueryWrapper<WxUserCurriculumSection>()
                    .eq(WxUserCurriculumSection::getCurriculumSectionId, curriculumSection.getId()));
            for (WxUserCurriculumSection wxUserCurriculumSection : wxUserCurriculumSections) {
                if (wxUserCurriculumSection.getIsPass() == 0) {
                    unPass = unPass + 1;
                }
                allNum = allNum + 1;
            }
        }
        wxUserCurriculumVo.setTestNum(allNum);
        wxUserCurriculumVo.setUnPassNum(unPass);
        //个人星级
        Integer start = businessCategoryRuleFeign.selectWxUserStart(wxUserId);
        if (start != null) {
            wxUserCurriculumVo.setStartLevel(start);
        }
        if (allNum != 0) {
            wxUserCurriculumVo.setPassRate((double) (allNum - unPass) / allNum * 100);
        }
        //学习时长柱状图
        List<Double> studyTime4days = Lists.newArrayList();
        //       List<String> studyDays = Lists.newArrayList();
        List<WxUserCurriculumStatisticsData> wxUserCurriculumStatisticsDatas = wxUserCurriculumStatisticsDataMapper.selectList(new LambdaQueryWrapper<WxUserCurriculumStatisticsData>()
                .eq(WxUserCurriculumStatisticsData::getWxUserId, wxUserId)
                .eq(WxUserCurriculumStatisticsData::getCurriculumId, curriculumId)
                .orderByAsc(WxUserCurriculumStatisticsData::getSaveTime));
//        for (WxUserCurriculumStatisticsData wxUserCurriculumStatisticsDatum : wxUserCurriculumStatisticsData) {
//            double studyTime4day = wxUserCurriculumStatisticsDatum.getStudyTime() / (60 * 60);
//            studyTime4days.add(studyTime4day);
//            studyDays.add(wxUserCurriculumStatisticsDatum.getSaveTime());
//        }

        List<String> saveTime = Lists.newArrayList();
        LocalDate startTime = LocalDate.now().minusDays(30);
        for (int i = 0; i <= LocalDate.now().getDayOfYear() - startTime.getDayOfYear(); i++) {
            saveTime.add(startTime.plusDays(i).toString());
        }
        List<Double> studyTimeList = Lists.newArrayList();
        for (String s : saveTime) {
            Long studyTime = 0L;
            //日期匹配
            for (WxUserCurriculumStatisticsData wxUserCurriculumStatisticsData : wxUserCurriculumStatisticsDatas) {
                if (s.equals(wxUserCurriculumStatisticsData.getSaveTime())) {
                    studyTime = wxUserCurriculumStatisticsData.getStudyTime();
                }
            }
            studyTimeList.add((double) studyTime / (60 * 60));
        }
        wxUserCurriculumVo.setStudyTime4days(studyTime4days);
        wxUserCurriculumVo.setStudyDays(saveTime);
        return new ReturnVO<>("个人学习情况详情查询成功", wxUserCurriculumVo);
    }

    @Autowired
    private IBusinessCategoryRuleFeign businessCategoryRuleFeign;

    @Override
    public FeignStudyTimeDto selectFeignStudyTimeDto(Long enterpriseId) {
        FeignStudyTimeDto feignStudyTimeDto = new FeignStudyTimeDto();
        String studyList = redisTemplate.opsForValue().get(RedisConstants.CURRICULUM_STUDY_DATA + enterpriseId);
        //查询七日人均学习时长
        List<StudyTimeDto> studyTimeDtos = JSONObject.parseArray(studyList, StudyTimeDto.class);
        double sevenStudyTime = 0;
        if (studyTimeDtos != null) {
            for (StudyTimeDto studyTimeDto : studyTimeDtos) {
                sevenStudyTime = sevenStudyTime + studyTimeDto.getStudyTime();
            }
        }
        feignStudyTimeDto.setSevenStudyTime((double) sevenStudyTime / (60 * 60));
        //计算人均学习时长
        double studyTime = 0;
        //查询人均学习时长
        List<WxUserCurriculumData> wxUserCurriculumDatas = wxUserCurriculumDataMapper.selectList(new LambdaQueryWrapper<WxUserCurriculumData>()
                .eq(WxUserCurriculumData::getEnterpriseId, enterpriseId));
        //学习总时长
        Long allStudyTime = 0L;
        for (WxUserCurriculumData wxUserCurriculumData : wxUserCurriculumDatas) {
            allStudyTime = allStudyTime + wxUserCurriculumData.getStudyTime();
            if (wxUserCurriculumDatas.size() == 0) {
                studyTime = 0;
            } else {
                studyTime = (double) allStudyTime / wxUserCurriculumDatas.size();
            }
        }
        //人均学习时长
        feignStudyTimeDto.setStudyTimePerson(studyTime / (60 * 60));
        return feignStudyTimeDto;
    }

    @Override
    public ReturnVO<StudyTimeVo> selectStudyTimeVoByEnterpriseId(Long enterpriseId) {
        StudyTimeVo studyTimeVo = new StudyTimeVo();
        String studyList = redisTemplate.opsForValue().get(RedisConstants.CURRICULUM_STUDY_DATA + enterpriseId);
        //查询七日人均学习时长
        List<StudyTimeDto> studyTimeDtos = JSONObject.parseArray(studyList, StudyTimeDto.class);
        List<String> studyTimeDtoListLocalDate = Lists.newArrayList();
        List<Double> studyTimeDtoListStudyTime = Lists.newArrayList();
        if (studyTimeDtos != null) {
            for (StudyTimeDto studyTimeDto : studyTimeDtos) {
                studyTimeDtoListLocalDate.add(studyTimeDto.getLocalDate());
                studyTimeDtoListStudyTime.add((double) studyTimeDto.getStudyTime() / (60 * 60));
            }
        }
        studyTimeVo.setStudyTimeDtoListLocalDate(studyTimeDtoListLocalDate);
        studyTimeVo.setStudyTimeDtoListStudyTime(studyTimeDtoListStudyTime);
        double sevenStudyTime = 0;
        if (studyTimeDtos != null) {
            for (StudyTimeDto studyTimeDto : studyTimeDtos) {
                sevenStudyTime = sevenStudyTime + studyTimeDto.getStudyTime();
            }
        }
        studyTimeVo.setSevenStudyTime((double) sevenStudyTime / (60 * 60));
        //查询人均学习时长
        List<WxUserCurriculumData> wxUserCurriculumDatas = wxUserCurriculumDataMapper.selectList(new LambdaQueryWrapper<WxUserCurriculumData>()
                .eq(WxUserCurriculumData::getEnterpriseId, enterpriseId));
        //计算人均学习时长
        double studyTime = 0;
        //学习总时长
        Long allStudyTime = 0L;
        for (WxUserCurriculumData wxUserCurriculumData : wxUserCurriculumDatas) {
            allStudyTime = allStudyTime + wxUserCurriculumData.getStudyTime();
            if (wxUserCurriculumDatas.size() == 0) {
                studyTime = 0;
            } else {
                studyTime = (double) allStudyTime / wxUserCurriculumDatas.size();
            }
        }
        //人均学习时长
        studyTimeVo.setStudyTimePerson((double) studyTime / (60 * 60));
        return new ReturnVO<>("学习时长查询成功", studyTimeVo);
    }

    @Autowired
    private WxUserCurriculumStatisticsDataMapper wxUserCurriculumStatisticsDataMapper;

    @SneakyThrows
    @Override
    public ReturnVO<JgPageVo<List<FeignWxUserDto>>> selectFeignWxUserDtoByCurriculum(HttpServletResponse response, Long enterpriseId, FeignWxUserDtoByCurriculumDto feignWxUserDtoByCurriculumDto) {
        PageHelper.startPage(feignWxUserDtoByCurriculumDto.getCurPage(), feignWxUserDtoByCurriculumDto.getMaxPage());
        UserCurriculumStatisticsDataDto userCurriculumStatisticsDataDto = new UserCurriculumStatisticsDataDto();
        userCurriculumStatisticsDataDto.setEndTime(LocalDate.now().toString());
        //近7天
        if (feignWxUserDtoByCurriculumDto.getLastDay() == 0) {
            userCurriculumStatisticsDataDto.setStartTime(LocalDate.now().minusDays(7).toString());
        }
        //近30天
        if (feignWxUserDtoByCurriculumDto.getLastDay() == 1) {
            userCurriculumStatisticsDataDto.setStartTime(LocalDate.now().minusDays(30).toString());
        }
        //近365天
        if (feignWxUserDtoByCurriculumDto.getLastDay() == 2) {
            userCurriculumStatisticsDataDto.setStartTime(LocalDate.now().minusDays(365).toString());
        }
        //查询用户信息
        List<WxUserCurriculumStatisticsData> wxUserCurriculumStatisticsData = wxUserCurriculumStatisticsDataMapper.selectSumByStudyTime(enterpriseId, userCurriculumStatisticsDataDto);
        List<FeignWxUserDto> feignWxUserDtoList = Lists.newArrayList();
        List<SelectFeignWxUserDtoByDocentVo> selectFeignWxUserDtoByDocentVos = Lists.newArrayList();
        for (WxUserCurriculumStatisticsData wxUserCurriculumStatisticsDatum : wxUserCurriculumStatisticsData) {
            FeignWxUserDto feignWxUserDto = wxUserApiFeign.selectFeignWxUserDtoByWxUserId(wxUserCurriculumStatisticsDatum.getWxUserId());
            feignWxUserDto.setStudyTime(wxUserCurriculumStatisticsDatum.getStudyTime() / (60 * 60));
            feignWxUserDtoList.add(feignWxUserDto);
            //导出
            SelectFeignWxUserDtoByDocentVo selectFeignWxUserDtoByDocentVo = new SelectFeignWxUserDtoByDocentVo();
            BeanUtils.copyProperties(feignWxUserDto, selectFeignWxUserDtoByDocentVo);
            selectFeignWxUserDtoByDocentVos.add(selectFeignWxUserDtoByDocentVo);
        }
        if (feignWxUserDtoByCurriculumDto.getIsExport() != null && feignWxUserDtoByCurriculumDto.getIsExport() == 1) {
            ExcelUtils.exportExcel(selectFeignWxUserDtoByDocentVos, "学习之星", "学习之星", SelectFeignWxUserDtoByDocentVo.class, "学习之星", response);
            return new ReturnVO("学习之星导出成功", null);
        }
        JgPageVo<Object> objectJgPageVo = new JgPageVo<>(new PageInfo(wxUserCurriculumStatisticsData));
        objectJgPageVo.setData(feignWxUserDtoList);
        return new ReturnVO("学习之星查询成功", objectJgPageVo);
    }

    @Autowired
    private WxUserTrainSurveyMapper wxUserTrainSurveyMapper;


    @Override
    public ReturnVO<WxUserCenterVo> selectWxUserCenterVo(Long wxUserId) {
        WxUserCurriculumData wxUserCurriculumData = wxUserCurriculumDataMapper.selectOne(new LambdaQueryWrapper<WxUserCurriculumData>()
                .eq(WxUserCurriculumData::getWxUserId, wxUserId));
        WxUserCenterVo wxUserCenterVo = new WxUserCenterVo();
        if (wxUserCurriculumData != null) {
            wxUserCenterVo.setStudyTime((double) wxUserCurriculumData.getStudyTime() / (60 * 60));
        }
        List<WxUserTrainSurvey> wxUserTrainSurveys = wxUserTrainSurveyMapper.selectList(new LambdaQueryWrapper<WxUserTrainSurvey>()
                .eq(WxUserTrainSurvey::getWxUserId, wxUserId)
                .eq(WxUserTrainSurvey::getExamStatus, 0));
        wxUserCenterVo.setTrainSurveyNum(wxUserTrainSurveys.size());
        Integer improveNum = enterpriseFeign.selectWxUserCenterImprove(wxUserId);
        if (improveNum != null) {
            wxUserCenterVo.setImproveNum(improveNum);
        }
        return new ReturnVO<>("查询个人中心数据成功", wxUserCenterVo);
    }

    @SneakyThrows
    @Override
    public ReturnVO<JgPageVo<List<FeignWxUserDto>>> selectFeignWxUserDtoByDocent(HttpServletResponse response, Long enterpriseId, FeignWxUserDtoByCurriculumDto feignWxUserDtoByCurriculumDto) {
        PageHelper.startPage(feignWxUserDtoByCurriculumDto.getCurPage(), feignWxUserDtoByCurriculumDto.getMaxPage());
        UserCurriculumStatisticsDataDto userCurriculumStatisticsDataDto = new UserCurriculumStatisticsDataDto();
        userCurriculumStatisticsDataDto.setEndTime(LocalDate.now().toString());
        //近7天
        if (feignWxUserDtoByCurriculumDto.getLastDay() == 0) {
            userCurriculumStatisticsDataDto.setStartTime(LocalDate.now().minusDays(7).toString());
        }
        //近30天
        if (feignWxUserDtoByCurriculumDto.getLastDay() == 1) {
            userCurriculumStatisticsDataDto.setStartTime(LocalDate.now().minusDays(30).toString());
        }
        //近365天
        if (feignWxUserDtoByCurriculumDto.getLastDay() == 2) {
            userCurriculumStatisticsDataDto.setStartTime(LocalDate.now().minusDays(365).toString());
        }
        //查询用户信息
        List<DocentCurriculumStatisticsData> docentCurriculumStatisticsDatas = docentCurriculumStatisticsDataMapper.selectSumByStudyTime(enterpriseId, userCurriculumStatisticsDataDto);
        List<FeignWxUserDto> feignWxUserDtoList = Lists.newArrayList();
        List<SelectDocentCurriculumStatisticsVo> selectDocentCurriculumStatisticsVos = Lists.newArrayList();
        for (DocentCurriculumStatisticsData docentCurriculumStatisticsData : docentCurriculumStatisticsDatas) {
            FeignWxUserDto feignWxUserDto = wxUserApiFeign.selectFeignWxUserDtoByDocentId(docentCurriculumStatisticsData.getDocentId());
            feignWxUserDto.setCurriculumNum(docentCurriculumStatisticsData.getCurriculumNum());
            if (feignWxUserDto.getId() == null) {
                feignWxUserDto.setNickname("该用户被删除");
            }
            feignWxUserDtoList.add(feignWxUserDto);
            //导出
            SelectDocentCurriculumStatisticsVo selectDocentCurriculumStatisticsVo = new SelectDocentCurriculumStatisticsVo();
            BeanUtils.copyProperties(feignWxUserDto, selectDocentCurriculumStatisticsVo);
            selectDocentCurriculumStatisticsVos.add(selectDocentCurriculumStatisticsVo);
        }
        if (feignWxUserDtoByCurriculumDto.getIsExport() != null && feignWxUserDtoByCurriculumDto.getIsExport() == 1) {
            ExcelUtils.exportExcel(selectDocentCurriculumStatisticsVos, "明星讲师", "明星讲师", SelectDocentCurriculumStatisticsVo.class, "明星讲师", response);
            return new ReturnVO("明星讲师导出成功", null);
        }
        JgPageVo<Object> objectJgPageVo = new JgPageVo<>(new PageInfo(docentCurriculumStatisticsDatas));
        objectJgPageVo.setData(feignWxUserDtoList);
        return new ReturnVO("学习之星查询成功", objectJgPageVo);
    }


    @Override
    public List<FeignWxUserDto> selectDocentCurriculumStatisticsVo(Long enterpriseId, FeignWxUserDtoByCurriculumDto feignWxUserDtoByCurriculumDto) {
        PageHelper.startPage(feignWxUserDtoByCurriculumDto.getCurPage(), feignWxUserDtoByCurriculumDto.getMaxPage());
        String endTime = LocalDate.now().toString();
        String startTime = null;
        //近7天
        if (feignWxUserDtoByCurriculumDto.getLastDay() == 0) {
            startTime = LocalDate.now().minusDays(7).toString();
        }
        //近30天
        if (feignWxUserDtoByCurriculumDto.getLastDay() == 1) {
            startTime = LocalDate.now().minusDays(30).toString();
        }
        //近365天
        if (feignWxUserDtoByCurriculumDto.getLastDay() == 2) {
            startTime = LocalDate.now().minusDays(365).toString();
        }
        //查询用户信息
        List<DocentCurriculumStatisticsVo> docentCurriculumStatisticsVos = curriculumMapper.selectDocentCurriculumStatisticsVo(enterpriseId, startTime, endTime);
        List<FeignWxUserDto> feignWxUserDtoList = Lists.newArrayList();
        for (DocentCurriculumStatisticsVo docentCurriculumStatisticsVo : docentCurriculumStatisticsVos) {
//            FeignWxUserDto feignWxUserDto = wxUserApiFeign.selectFeignWxUserDtoByWxUserId(wxUserCurriculumStatisticsDatum.getWxUserId());
//            feignWxUserDtoList.add(feignWxUserDto);
        }
        curriculumMapper.selectDocentCurriculumStatisticsVo(enterpriseId, startTime, endTime);
        return null;
    }

    @Override
    public Integer countByCourse() {
        return curriculumMapper.selectCount(new QueryWrapper<>());
    }

    @Override
    public ReturnVO<CountStudyStatisticsVo> countStudyPersonNum() {
        CountStudyStatisticsVo countStudyStatisticsVo = new CountStudyStatisticsVo();
        //展示近30天日期
        List<String> saveTime = Lists.newArrayList();
        LocalDate startTime = LocalDate.now().minusDays(30);
        for (int i = 0; i < 30; i++) {
            saveTime.add(startTime.plusDays(i).toString());
        }
        countStudyStatisticsVo.setSaveTime(saveTime);
        List<Integer> studyPeronNum = Lists.newArrayList();
        for (String s : saveTime) {
            Integer count = curriculumMapper.selectCountStudyStatisticsVo(s, s);
            studyPeronNum.add(count);
        }
        countStudyStatisticsVo.setStudyPeronNum(studyPeronNum);
        return new ReturnVO<>("平台学习人数查询成功", countStudyStatisticsVo);
    }

    @Override
    public ReturnVO<CountStudyEnterpriseStatisticsVo> selectCountStudyEnterpriseStatisticsVo(Long enterpriseId) {
        CountStudyEnterpriseStatisticsVo countStudyEnterpriseStatisticsVo = new CountStudyEnterpriseStatisticsVo();
        //展示近30天日期
        List<String> saveTime = Lists.newArrayList();
        LocalDate startTime = LocalDate.now().minusDays(30);
        for (int i = 0; i < 30; i++) {
            saveTime.add(startTime.plusDays(i).toString());
        }
        countStudyEnterpriseStatisticsVo.setSaveTime(saveTime);
        double allStudyTime = 0;
        List<Double> studyTime = Lists.newArrayList();
        for (String s : saveTime) {
            Long aLong = curriculumMapper.countCountStudyEnterpriseStatisticsVo(enterpriseId, s, LocalDate.parse(s).plusDays(1).toString());
            if (aLong != null) {
                studyTime.add((double) aLong / (60 * 60));
                allStudyTime = allStudyTime + ((double) aLong / (60 * 60));
            } else {
                studyTime.add((double) 0);
            }

        }
        countStudyEnterpriseStatisticsVo.setStudyTime(studyTime);
        countStudyEnterpriseStatisticsVo.setAllStudyTime(allStudyTime);
        //学习次数 统计章节的考试次数
        Integer studyNum = wxUserCurriculumSectionMapper.selectCount(new LambdaQueryWrapper<WxUserCurriculumSection>()
                .eq(WxUserCurriculumSection::getEnterpriseId, enterpriseId));
        countStudyEnterpriseStatisticsVo.setStudyNum(studyNum);
        return new ReturnVO<>("当前企业的学习数据查询成功", countStudyEnterpriseStatisticsVo);
    }

    @Override
    public Integer selectCountByEnterpriseId(Long enterpriseId) {
        return curriculumMapper.selectCount(new LambdaQueryWrapper<Curriculum>()
                .eq(Curriculum::getEnterpriseId, enterpriseId));
    }

    @Override
    public ReturnVO<CountStudyWxUserStatisticsVo> selectCountStudyWxUserStatisticsVo(SelectCountStudyWxUserStatisticsDto selectCountStudyWxUserStatisticsDto) {
        CountStudyWxUserStatisticsVo countStudyWxUserStatisticsVo = new CountStudyWxUserStatisticsVo();
        if (StringUtils.isBlank(selectCountStudyWxUserStatisticsDto.getStartTime()) || StringUtils.isBlank(selectCountStudyWxUserStatisticsDto.getEndTime())) {
            throw new ServiceException("请传入开始和结束时间");
        }
        List<EnterpriseCurriculumDto> enterpriseCurriculumDtos = wxUserCurriculumStatisticsDataMapper.listWxUserCurriculumDto(selectCountStudyWxUserStatisticsDto.getWxUserId(), selectCountStudyWxUserStatisticsDto.getStartTime(), selectCountStudyWxUserStatisticsDto.getEndTime());
        List<String> saveTime = Lists.newArrayList();
        LocalDate startTime = LocalDate.parse(selectCountStudyWxUserStatisticsDto.getStartTime());
        LocalDate endTime = LocalDate.parse(selectCountStudyWxUserStatisticsDto.getEndTime());
        for (int i = 0; i < endTime.getDayOfYear() - startTime.getDayOfYear(); i++) {
            saveTime.add(startTime.plusDays(i).toString());
        }
        List<Double> studyTimeList = Lists.newArrayList();
        for (String s : saveTime) {
            Long studyTime = 0L;
            //日期匹配
            for (EnterpriseCurriculumDto enterpriseCurriculumDto : enterpriseCurriculumDtos) {
                if (s.equals(enterpriseCurriculumDto.getSaveTime())) {
                    studyTime = enterpriseCurriculumDto.getStudyTime();
                }
            }
            studyTimeList.add((double) studyTime / (60 * 60));
        }
        countStudyWxUserStatisticsVo.setSaveTime(saveTime);
        countStudyWxUserStatisticsVo.setStudyTime(studyTimeList);
        return new ReturnVO<>("职员用户的每日学习时长查询成功", countStudyWxUserStatisticsVo);
    }

    @SneakyThrows
    @Transactional
    @Override
    public ReturnVO importTopicSection(String token, Long curriculumSectionId, MultipartFile file) {
        //接口幂等处理
        Boolean aBoolean = redisTemplate.opsForValue().setIfAbsent(RedisConstants.TOPIC_IMPORT + token, token, 5, TimeUnit.SECONDS);
        if (!Boolean.TRUE.equals(aBoolean)) {
            throw new ServiceException("操作太频繁,请5秒后再试");
        }
        ExcelTopicUtils excelUtil = new ExcelTopicUtils();
        Workbook wb = excelUtil.getExcel(file);
        Sheet sheet = wb.getSheetAt(0);//读取sheet(从0计数)
        int rowNum = sheet.getLastRowNum();//读取行数(从0计数)
        int i = 0;
        try {
            Long topicId = null;//题目id
            CurriculumSectionTopic topic = null;//题目
            Long topicAnswerId = null;//答案id
            CurriculumSectionTopicAnswer topicAnswer = null;//答案选项
            for (; i <= rowNum; i++) {
                if (i < 1) {
                    //不读前两行
                    continue;
                }
                Row row = sheet.getRow(i);//获得行
                for (int j = 0; j < 7; j++) {
                    Cell cell = row.getCell(j);//获取单元格
                    //题目名称 如果题目名称为空 则让答案选项关联上一个题目数据
                    if (cell != null && StringUtils.isNotBlank(cell.toString())) {
                        //题目id
                        if (j == 0) {
                            topicId = Long.valueOf(cell.toString());
                        }
                        if (j == 1) {
                            topic = new CurriculumSectionTopic();
                            topic.setTopicCategory(0);
                            topic.setCurriculumSectionId(curriculumSectionId);
                            topic.setTopicName(cell.toString());
                        }
                        //设置限制个数 对象最后的一个属性进行操作
                        if (j == 2) {
                            topic.setChooseNum(excelUtil.format(cell.toString()));
                            if (topicId == null) {
                                curriculumSectionTopicMapper.insert(topic);
                            } else {
                                topic.setId(topicId);
                                curriculumSectionTopicMapper.updateById(topic);
                                topicId = null;//置空
                            }
                        }
                        //答案id
                        if (j == 3) {
                            topicAnswerId = Long.valueOf(cell.toString());
                        }
                        //选项
                        if (j == 4) {
                            topicAnswer = new CurriculumSectionTopicAnswer();
                            topicAnswer.setCurriculumSectionTopicId(topic.getId());
                            topicAnswer.setItem(cell.toString());
                        }
                        //答案
                        if (j == 5) {
                            topicAnswer.setAnswer(cell.toString());
                        }
                        //分数
                        if (j == 6) {
                            topicAnswer.setScore(new BigDecimal(cell.toString()));
                            if (topicAnswerId == null) {
                                curriculumSectionTopicAnswerMapper.insert(topicAnswer);
                            } else {
                                topicAnswer.setId(topicAnswerId);
                                curriculumSectionTopicAnswerMapper.updateById(topicAnswer);
                                topicAnswerId = null;//置空
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("导入测评题库出错[{}]", e.getMessage());
            throw new ServiceException("第" + (i + 1) + "行出错");
        }
        return new ReturnVO("题库导入成功", null);
    }

    @Override
    public void exportTopicSection(HttpServletResponse response, Long curriculumSectionId) {
        CurriculumSection curriculumSection = curriculumSectionMapper.selectById(curriculumSectionId);
        Optional.ofNullable(curriculumSection).orElseThrow(() -> new ServiceException("该章节不存在"));
        List<CurriculumSectionTopic> curriculumSectionTopics = curriculumSectionTopicMapper.selectList(new LambdaQueryWrapper<CurriculumSectionTopic>()
                .eq(CurriculumSectionTopic::getCurriculumSectionId, curriculumSection.getId()));
        List<ExportTopicSectionVo> exportTopicSectionVos = Lists.newArrayList();
        for (CurriculumSectionTopic curriculumSectionTopic : curriculumSectionTopics) {
            ExportTopicSectionVo exportTopicSectionVo = new ExportTopicSectionVo();
            BeanUtils.copyProperties(curriculumSectionTopic, exportTopicSectionVo);
            List<CurriculumSectionTopicAnswer> curriculumSectionTopicAnswers = curriculumSectionTopicAnswerMapper.selectList(new LambdaQueryWrapper<CurriculumSectionTopicAnswer>()
                    .eq(CurriculumSectionTopicAnswer::getCurriculumSectionTopicId, curriculumSectionTopic.getId()));
            List<ExportTopicAnswerVo> exportTopicAnswerVoList = Lists.newArrayList();
            for (CurriculumSectionTopicAnswer curriculumSectionTopicAnswer : curriculumSectionTopicAnswers) {
                ExportTopicAnswerVo exportTopicAnswerVo = new ExportTopicAnswerVo();
                BeanUtils.copyProperties(curriculumSectionTopicAnswer, exportTopicAnswerVo);
                exportTopicAnswerVoList.add(exportTopicAnswerVo);
            }
            exportTopicSectionVo.setExportTopicAnswerVos(exportTopicAnswerVoList);
            exportTopicSectionVos.add(exportTopicSectionVo);
        }


        try {
            // 设置响应输出的头类型
            response.setHeader("content-Type", "application/vnd.ms-excel");
            // 下载文件的默认名称
            response.setHeader("Content-Disposition", "attachment;filename=章节测评题.xls");

            ExportParams deptExportParams = new ExportParams();
            // 设置sheet得名称
            deptExportParams.setSheetName("章节测评题");

            Map<String, Object> deptExportMap = new HashMap<>();
            // title的参数为ExportParams类型，目前仅仅在ExportParams中设置了sheetName
            deptExportMap.put("title", deptExportParams);
            // 模版导出对应得实体类型
            deptExportMap.put("entity", ExportTopicSectionVo.class);
            // sheet中要填充得数据
            deptExportMap.put("data", exportTopicSectionVos);

            List<Map<String, Object>> sheetsList = new ArrayList<>();
            sheetsList.add(deptExportMap);
            Workbook workbook = ExcelExportUtil.exportExcel(sheetsList, ExcelType.HSSF);
            ServletOutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @Override
    public void courseUpdate(Long curriculumId) {
        Curriculum curriculum = curriculumMapper.selectById(curriculumId);
        Optional.ofNullable(curriculum).orElseThrow(() -> new ServiceException("该课程不存在"));
        List<Curriculum> curriculumList = curriculumMapper.selectList(new LambdaQueryWrapper<Curriculum>()
                .eq(Curriculum::getOldCurriculumId, curriculum.getId()));


    }

    @Autowired
    private CurriculumCategoryMapper curriculumCategoryMapper;

    @Override
    public ReturnVO isHaveCategoryAndDocent(Long enterpriseId) {
        Integer categoryCount = curriculumCategoryMapper.selectCount(new LambdaQueryWrapper<CurriculumCategory>().eq(CurriculumCategory::getEnterpriseId, enterpriseId));
        if (categoryCount == 0) {
            return new ReturnVO("请去添加课程一级与二级分类", 1);
        }
        Integer docentCount = docentFeign.selectCountByDocent(enterpriseId);
        if (docentCount == 1) {
            return new ReturnVO("请去添加讲师", 2);
        }
        return new ReturnVO("允许添加课程", 0);
    }

    // ========== 内部方法 ==========

    /**
     * 处理文件对象
     *
     * @param curriculum
     * @return
     */
    private List<CurriculumFileVo> getCurriculumFileVos(Curriculum curriculum) {
        if (curriculum != null && StringUtils.isNotBlank(curriculum.getCurriculumFile())) {
            if (curriculum.getCurriculumFile() != null && curriculum.getCurriculumFileName() != null && curriculum.getCurriculumFileSize() != null) {
                String[] files = curriculum.getCurriculumFile().split(",");
                String[] fileNames = curriculum.getCurriculumFileName().split(",");
                String[] fileSizes = curriculum.getCurriculumFileSize().split(",");
                List<CurriculumFileVo> curriculumFileVos = Lists.newArrayList();
                for (int i = 0; i < files.length; i++) {
                    CurriculumFileVo curriculumFileVo = new CurriculumFileVo();
                    curriculumFileVo.setCurriculumFile(files[i]);
                    curriculumFileVo.setCurriculumFileName(fileNames[i]);
                    curriculumFileVo.setCurriculumFileSize(fileSizes[i]);
                    curriculumFileVos.add(curriculumFileVo);
                }
                return curriculumFileVos;
            }
        }
        return null;
    }

}
